/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtDebug>
#include <QTextBoundaryFinder>
#include <QCoreApplication>
#include <QHash>
#include <QPair>
#include <QStringList>
#include <QTextStream>
#include <QUrl>
#include <QRegExp>

#include "qapplicationargument_p.h"

#include "qapplicationargumentparser_p.h"

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
 \class QApplicationArgumentParser
 \brief The QApplicationArgumentParser class parses the command
        line arguments for an application.
 \reentrant
 \internal
 \since 4.4

 QApplicationArgumentParser simplifies writing command line applications by taking care of:

 \list
    \li Generating help and version arguments
    \li Taking care of converting arguments to QVariant types, since each argument
       has a type: QApplicationArgument::type()
    \li Validates the command line such that the user operates on well-defined input. For instance,
       that the argument is a valid integer if that is the case, that an argument does not
       occur more times than allowed, and so on.
    \li Allows customization through sub-classing.
 \endlist

 The user declares what arguments that can be given to the application with QApplicationArgument. Provided
 with that information, QApplicationArgumentParser takes care of parsing the actual
 command line, appropriately flag errors, generate help messages, and provide
 convenient access to the values of the arguments.

 The way to use it is to create a set of QApplicationArgument by ones choosing, call
 addArgument() for each, and subsequently call parse(). If parse() returns \c false,
 the caller should exit and return exitCode().

 If parse() returns \c true the command line was successfully parsed, its
 values are well-defined, and they can be spectated with count(),
 has(), value() and values().

 \snippet doc/src/snippets/code/tools_patternist_qapplicationargumentparser.cpp 0

 For arguments without a name(such as filename passed to the \c ls utility on Linux) add a
 QApplicationArgument that does not have a name. The minimum and maximum occurrences will be
 respected as usual and the type applies too.

 QApplicationArgumentParser always has two options builtin: \c version and \c help.

 \section1 Changing Parsing Convention

 QApplicationArgumentParser by default parses the command line in the style
 of Qt's utilities, where arguments are preceded by a single dash, and identified
 by a single name. However, in some cases it might be of interest to parse
 another style, such as the well-established UNIX \c getopt convention(\c -l
 and \c --long).

 This can be achieved by sub-classing QApplicationArgumentParser and reimplementing
 parse(). It would do the following:

 \list
    \li Call input() to retrieve the strings the user specified on the command line.
    \li Call declaredArguments() to retrieve the arguments that the implementor has
       decided can be specified.
    \li Parse and validate the input. Salt and pepper as per taste.
    \li If an error occurred, call setExitCode() and return \c false.
    \li Otherwise, call setExitCode(Success), provide access to the
       arguments by calling setUsedArguments(), and return \c true. If a
       help message was requested, call setExitCode(Success) and return \c false.
 \endlist

 \sa QApplicationArgument, QCoreApplication
*/
class QApplicationArgumentParserPrivate
{
    Q_DECLARE_TR_FUNCTIONS(QApplicationArgumentParserPrivate)
public:
    // TODO Isn't it like ten times better with QHash<QApplicationArgument, QList<QVariant> >?
    // TODO test QApplicationArgument::nameless()
    typedef QList<QPair<QApplicationArgument, QVariant> > UsedList;

    /*!
     We initialize exitCode to ParseError such that we consciously flag success.
     */
    inline QApplicationArgumentParserPrivate(QApplicationArgumentParser *const master,
                                             const QStringList &aInput) : exitCode(QApplicationArgumentParser::ParseError)
                                                                        , input(aInput)
                                                                        , q_ptr(master)
    {
        Q_ASSERT(!aInput.isEmpty());
    }

    QApplicationArgument nextNamelessArgument() const;
    static QStringList argumentsFromLocal(const int argc, const char *const *const argv);

    bool error(const QString &message);
    static bool errorMessage(const QString &message);
    static inline bool isSwitch(const QApplicationArgument &arg);
    static inline QVariant conversionError(const QString &typeName,
                                           const QString &input);
    int count(const QApplicationArgument &arg) const;
    bool contains(const QApplicationArgument &arg) const;
    static inline bool isBuiltinVariant(const int type);
    void displayVersion() const;
    void displayHelp() const;
    void parseNameless();
    bool parseNamelessArguments(const QString &in);

    QApplicationArgumentParser::ExitCode    exitCode;
    const QStringList                       input;

    /*!
      Since the QString is QApplicationArgument::name() anyway, why
      not use a QSet?
     */
    QHash<QString, QApplicationArgument>    declaredArguments;

    QList<QApplicationArgument>             declaredNamelessArguments;

    UsedList                                usedArguments;
    QString                                 applicationDescription;
    QString                                 applicationVersion;

private:
    QApplicationArgumentParser *const       q_ptr;
    Q_DECLARE_PUBLIC(QApplicationArgumentParser)

    static QString lineWrap(const QString &input,
                            const int leftIndent,
                            const int width);
    static QList<QApplicationArgument> builtinArguments();
};

QApplicationArgument QApplicationArgumentParserPrivate::nextNamelessArgument() const
{
    /* Count how many nameless arguments we have so far. */
    int count = 0;

    for(int i = 0; i < usedArguments.count(); ++i)
    {
        if(usedArguments.at(i).first.isNameless())
            ++count;
    }

    /* TODO this doesn't work for arguments that have more than one
     * mandatory value(e.g nameless ones), since several values should
     * then only count for one argument. */
    for(int i = 0; i < declaredNamelessArguments.count(); ++i)
    {
        if(count)
        {
            /* Skip the ones we already have processed. */
            --count;
            continue;
        }

        if(declaredNamelessArguments.at(i).isNameless())
            return declaredNamelessArguments.at(i);
    }

    return QApplicationArgument();
}

int QApplicationArgumentParserPrivate::count(const QApplicationArgument &arg) const
{
    const int len = usedArguments.count();
    int count = 0;

    for(int i = 0; i < len; ++i)
    {
        if(usedArguments.at(i).first == arg)
            ++count;
    }

    return count;
}

/*!
 Returns \c true if \a arg has appeared on the command line, not whether it has been declared.
 */
bool QApplicationArgumentParserPrivate::contains(const QApplicationArgument &arg) const
{
    const int len = usedArguments.count();

    for(int i = 0; i < len; ++i)
    {
        if(usedArguments.at(i).first == arg)
            return true;
    }

    return false;
}

/*!
 Returns always \c false.
 */
bool QApplicationArgumentParserPrivate::error(const QString &message)
{
    exitCode = QApplicationArgumentParser::ParseError;
    errorMessage(message);
    return errorMessage(tr("Pass -help for information about the command line."));
}

/*!
 Returns always \c false.
 */
bool QApplicationArgumentParserPrivate::errorMessage(const QString &message)
{
    QTextStream out(stderr, QIODevice::WriteOnly);
    out << message << Qt::endl;
    return false;
}

/*!
  \internal
  Determines whether \a arg carries a value or is on/off.
 */
bool QApplicationArgumentParserPrivate::isSwitch(const QApplicationArgument &arg)
{
    return arg.type() == QVariant::Invalid;
}

QVariant QApplicationArgumentParserPrivate::conversionError(const QString &typeName,
                                                            const QString &input)
{
    errorMessage(tr("Cannot convert %1 to type %2.").arg(input, typeName));
    return QVariant();
}

bool QApplicationArgumentParserPrivate::isBuiltinVariant(const int type)
{
    return type < int(QVariant::UserType);
}

/*!
  TODO Temporary, replace with a function in QCoreApplication.
*/
QStringList QApplicationArgumentParserPrivate::argumentsFromLocal(const int argc, const char *const *const argv)
{
    Q_ASSERT(argc >= 1);
    Q_ASSERT(argv);
    QStringList result;

    for(int i = 0; i < argc; ++i)
        result.append(QString::fromLocal8Bit(argv[i]));

    return result;
}

void QApplicationArgumentParserPrivate::displayVersion() const
{
    QTextStream out(stderr);

    out << tr("%1 version %2 using Qt %3").arg(QCoreApplication::applicationName(), applicationVersion, QString::fromLatin1(qVersion()))
        << Qt::endl;
}

void QApplicationArgumentParserPrivate::displayHelp() const
{
    enum Constants
    {
        /**
         * When we want to line wrap, 80 minus a couple of characters. This should
         * be suitable for vt100 compatible terminals.
         */
        LineWrapAt = 78,

        /**
         * The initial "  -" for each option.
         */
        IndentPadding = 3,

        /**
         * Pad for the brackets and space we use when we have a type.
         */
        ValueArgumentPadding = 4
    };

    QList<QApplicationArgument> args(declaredArguments.values());
    args += builtinArguments();

    /* Sort them, such that we get the nameless options at the end, and it
     * generally looks tidy. */
    std::sort(args.begin(), args.end());

    /* This is the basic approach:
     * Switches:
     *  -name description
     * Value arguments:
     *  -name <name-of-value-type> description
     *
     * Nameless arguments
     *  name <type> description
     *
     * It all line-wraps at OutputWidth and the description is indented,
     * where the highest indent is the length of the name plus length of the name
     * of the type. */

    /* First we find the name with the largest width. */
    int maxWidth = 0;

    QList<QApplicationArgument> nameless(declaredNamelessArguments);
    std::sort(nameless.begin(), nameless.end());

    /* Note, here the nameless arguments appear last, but are sorted
     * with themselves. */
    QList<QApplicationArgument> allArgs(args + nameless);
    const int allArgsCount = allArgs.count();

    for(int i = 0; i < allArgsCount; ++i)
    {
        const QApplicationArgument &at = allArgs.at(i);
        const int nameLength = at.name().length();
        const QString typeName(q_ptr->typeToName(at));
        const int typeNameLength = typeName.length();
        const int padding = at.type() == QVariant::Invalid ? 0 : ValueArgumentPadding;
        maxWidth = qMax(maxWidth, nameLength + typeNameLength + padding);
    }

    QTextStream out(stderr);
    out << Qt::endl
        << QString(IndentPadding, QLatin1Char(' '))
        << QCoreApplication::applicationName()
        << QLatin1String(" -- ")
        << applicationDescription
        << Qt::endl;
    // TODO synopsis

    /* One extra so we get some space between the overview and the options. */
    out << Qt::endl;

    const int indentWidth = maxWidth + 3;

    /* Ok, print them out. */
    for(int i = 0; i < allArgsCount; ++i)
    {
        const QApplicationArgument &at = allArgs.at(i);
        /* "  -name ". Indent a bit first, inspired by Qt's moc. */
        const QString &name = at.name();
        QString prolog(QLatin1String("  "));

        /* We have a special case for the single dash. */
        if(name == QChar::fromLatin1('-'))
            prolog.append(name);
        else
        {
            if(!at.isNameless())
                prolog.append(QLatin1Char('-'));

             prolog.append(name + QLatin1Char(' '));
        }

        if(at.type() != QVariant::Invalid)
        {
            /* It's not a switch, it has a value. */

            /* Do we have a default value? If so, the argument is optional. */
            const QString typeName(q_ptr->typeToName(at));

            if(at.defaultValue().isValid())
                prolog.append(QLatin1Char('[') + typeName + QLatin1Char(']'));
            else
                prolog.append(QLatin1Char('<') + typeName + QLatin1Char('>'));
            // TODO Don't we want to display the default value?

            prolog.append(QLatin1Char(' '));
        }

        prolog = prolog.leftJustified(indentWidth);

        out << prolog
            << lineWrap(at.description(), indentWidth, LineWrapAt)
            << Qt::endl;
    }
}

/*!
 Line wraps \a input and indents each line with \a leftIndent spaces, such that
 the width does not go beyond \a maxWidth.

 The addition of line endings is accounted for by the caller.

 With QTextBoundaryFinder our line wrapping is relatively fancy, since it
 does it the Unicode-way.
 */
QString QApplicationArgumentParserPrivate::lineWrap(const QString &input,
                                                    const int leftIndent,
                                                    const int maxWidth)
{
    const QString indent(QString(leftIndent, QLatin1Char(' ')));
    const int len = input.length();
    const int textWidth = maxWidth - leftIndent;

    QString output;
    QTextBoundaryFinder wrapFinder(QTextBoundaryFinder::Line, input);
    wrapFinder.setPosition(textWidth);

    if(input.length() + leftIndent <= maxWidth)
        return input;

    int from = wrapFinder.toPreviousBoundary();
    output.append(input.leftRef(from));

    while(true)
    {
        if((len - from) + leftIndent > maxWidth)
        {
            /* We need to line wrap. */
            wrapFinder.setPosition(from + textWidth);
            const int currentWidthPos = wrapFinder.toPreviousBoundary();

            output.append(QLatin1Char('\n'));
            output.append(indent);
            output.append(input.midRef(from, currentWidthPos - from).trimmed().toString());
            from += (currentWidthPos - from);
        }
        else
        {
            /* Append the remains.  */
            output.append(QLatin1Char('\n'));
            output.append(indent);
            output.append(input.midRef(from).trimmed().toString());
            break;
        }
    }

    return output;
}

/*!
 Returns a list with the builtin options that the parser has
 */
QList<QApplicationArgument> QApplicationArgumentParserPrivate::builtinArguments()
{
    QList<QApplicationArgument> result;

    result.append(QApplicationArgument(QLatin1String("help"),
                                       QLatin1String("Displays this help.")));
    result.append(QApplicationArgument(QLatin1String("version"),
                                       QLatin1String("Displays version information.")));

    result.append(QApplicationArgument(QLatin1String("-"),
                                       QLatin1String("When appearing, any following options are not interpreted as switches.")));
    return result;
}

/* TODO, I don't think we want this function in a public API. Add it first when there is a demand. */

/*!
 Creates a QApplicationArgumentParser that will parse the input in \a argc and \a argv.
These arguments should be passed directly from the \c main() function, and the decoding
of the input will be taken care of appropriately, depending on platform.

 It is preferred to use the QStringList overload, in case the input is in the form of QStrings.
 */
QApplicationArgumentParser::QApplicationArgumentParser(int argc, char **argv) : d(new QApplicationArgumentParserPrivate(this, QApplicationArgumentParserPrivate::argumentsFromLocal(argc, argv)))
{
    Q_ASSERT_X(argv, Q_FUNC_INFO, "Argv cannot be null.");
    Q_ASSERT_X(argc >= 1, Q_FUNC_INFO,
               "argc must at least contain the application name. "
               "Use the QStringList overload instead.");
}

/*!
 \overload

 Creates a QApplicationArgumentParser that will parse \a input. That is, instead of passing in \c argc
 and \c argv, one can pass in a QStringList.

 The caller guarantees that the first string in \a input is the name of the application.
 */
QApplicationArgumentParser::QApplicationArgumentParser(const QStringList &input) : d(new QApplicationArgumentParserPrivate(this, input))
{
    Q_ASSERT_X(input.count() >= 1, Q_FUNC_INFO,
               "The input must at least contain the application name.");
}

/*!
 This function is only of interest when subclassing.

 Returns the strings that the user specified when starting the application. The first string
 in the list is always the application name.
 */
QStringList QApplicationArgumentParser::input() const
{
    Q_ASSERT_X(d->input.count() >= 1, Q_FUNC_INFO, "Internal error, this should always hold true");
    return d->input;
}

/*!
 This function is only of interest when subclassing.

 Sets the arguments that the user actually used on the command line to \a arguments.
 The parse() function should call this, such that the result afterwards can be inspected
 with for instance has() or count().

\sa usedArguments()
*/
void QApplicationArgumentParser::setUsedArguments(const QList<QPair<QApplicationArgument, QVariant> > &arguments)
{
    d->usedArguments = arguments;
}

/*!
 This function is only of interest when subclassing.

 Returns the arguments that the user used on the command line.

\sa setUsedArguments()
*/
QList<QPair<QApplicationArgument, QVariant> > QApplicationArgumentParser::usedArguments() const
{
    return d->usedArguments;
}

/*!
  Destructs this QApplicationArgumentParser instance.
 */
QApplicationArgumentParser::~QApplicationArgumentParser()
{
    delete d;
}

/*!
  Adds \a argument to this parser.

  This function is provided for convenience. It is equivalent to creating a QList
  containing \a argument, append the existing arguments, and then call setDeclaredArguments() with the list.

  \sa setDeclaredArguments()
 */
void QApplicationArgumentParser::addArgument(const QApplicationArgument &argument)
{
    if(argument.isNameless())
        d->declaredNamelessArguments.append(argument);
    else
        d->declaredArguments.insert(argument.name(), argument);
}

/*!
 Makes the parser recognize all arguments in \a arguments.

 Any arguments previously set, are discarded.

 \sa addArgument(), declaredArguments()
 */
void QApplicationArgumentParser::setDeclaredArguments(const QList<QApplicationArgument> &arguments)
{
    // TODO If we have a QHash internally, why not use it in the public API too?
    const int len = arguments.count();

    for(int i = 0; i < len; ++i)
        d->declaredArguments.insert(arguments.at(i).name(), arguments.at(i));
}

/*!
 Returns the arguments that this parser recognizes.

 \sa addArgument(), setDeclaredArguments()
 */
QList<QApplicationArgument> QApplicationArgumentParser::declaredArguments() const
{
    return d->declaredArguments.values();
}

bool QApplicationArgumentParserPrivate::parseNamelessArguments(const QString &in)
{
    /* It's a nameless options, such as simply "value". */
    const QApplicationArgument nameless(nextNamelessArgument());

    const QVariant val(q_ptr->convertToValue(nameless, in));
    if(val.isValid())
    {
        usedArguments.append(qMakePair(nameless, val));
        return true;
    }
    else
        return false; // TODO error msg?
}

/*!
 Parses input() together with declaredArguments() and returns \c false if the caller
 should exit immediately, which is the case of which an error was encountered or
 help or the version was requested.

 In the case of \c true was returned, valid arguments were supplied, and they can
 be requested with functions like value(), values(), count() and has().

 parse() must only be called once per QApplicationArgumentParser instance. The
 second time it's called, the effects and return value are undefined.

 \sa convertToValue(), typeToName()
 */
bool QApplicationArgumentParser::parse()
{
    const QChar sep(QLatin1Char('-'));
    const int inputCount = d->input.count();

    /* We skip the first entry, which is the application name. */
    int i = 1;

    for(; i < inputCount; ++i)
    {
        const QString &in = d->input.at(i);

        /* We have a single '-', signalling that the succeeding are not options. */
        if(in == sep)
        {
            ++i;

            for(; i < inputCount; ++i)
            {
                if(!d->parseNamelessArguments(d->input.at(i)))
                    return false;
                /* Process nameless options. Have code for this elsewhere, factor it out. */
            }

            break;
        }

        if(in.startsWith(sep)) /* It is "-name". */
        {
            const QString name(in.mid(1));

            if(name == QLatin1String("help"))
            {
                setExitCode(Success);
                d->displayHelp();
                return false;
            }
            else if(name == QLatin1String("version"))
            {
                setExitCode(Success);
                d->displayVersion();
                return false;
            }

            if(!d->declaredArguments.contains(name))
                return d->error(QApplicationArgumentParserPrivate::tr("\"%1\" is an unknown argument.").arg(name));

            const QApplicationArgument &arg = d->declaredArguments.value(name);
            const int argCount = d->count(arg) + 1;
            const int max = arg.maximumOccurrence();

            if(argCount > max && max != -1)
            {
                /* Let's tailor the message for a common case. */
                if(max == 1)
                    return d->error(QApplicationArgumentParserPrivate::tr("\"%1\" can only be used once.").arg(name));
                else
                    return d->error(QApplicationArgumentParserPrivate::tr("\"%1\" can only be used %2 times.").arg(name, QString::number(max)));
            }

            if(QApplicationArgumentParserPrivate::isSwitch(arg))
            {
                d->usedArguments.append(qMakePair(arg, QVariant()));
                continue;
            }
            else
            {
                ++i;

                if(i == inputCount)
                    return d->error(QApplicationArgumentParserPrivate::tr("\"%1\" must be followed by a value.").arg(name));

                /* Okidoki, got a value, always something. Let's
                 * see if it validates. */
                const QString &value = d->input.at(i);

                const QVariant val(convertToValue(arg, value));
                if(val.isValid())
                {
                    d->usedArguments.append(qMakePair(arg, val));
                    continue;
                }
                else
                    return false; // TODO error msg?
            }
        }
        else
        {
            if(!d->parseNamelessArguments(in))
                return false;
        }
    }

    /* Check that all arguments that have been declared as mandatory, are actually
     * specified. */
    const QList<QApplicationArgument> declaredArguments(d->declaredArguments.values() + d->declaredNamelessArguments);
    const int len = declaredArguments.count();
    for(int i = 0; i < len; ++i)
    {
        const QApplicationArgument &at = declaredArguments.at(i);
        const int min = at.minimumOccurrence();
        const int max = at.maximumOccurrence(); // TODO What about infinite? -1
        if(min == 0)
            continue;
        else
        {
            const int usedLen = d->usedArguments.count();
            int useCount = 0;

            for(int u = 0; u < usedLen; ++u)
            {
                const QPair<QApplicationArgument, QVariant> &used = d->usedArguments.at(u);
                if(used.first == at)
                    ++useCount;
            }

            const QString originalName(at.name());
            const QString effectiveName(originalName.isEmpty() ? QLatin1Char('<') + typeToName(at) + QLatin1Char('>') : originalName);

            if(useCount < min)
            {
                /* For nameless options, we use the type as the name. Looks better. */
                return d->error(QApplicationArgumentParserPrivate::tr("%1 must occur at least %2 times, therefore %3 times is insufficient.", "The number is for %2.", min)
                                                                      .arg(effectiveName, QString::number(min), QString::number(useCount)));
            }
            else if(useCount > max)
                return d->error(QApplicationArgumentParserPrivate::tr("%1 can occur at most %2 times", "", max).arg(effectiveName, QString::number(max)));
        }
    }

    d->exitCode = Success;
    return true;
}

/*!
 This function is only of interest when subclassing.

 parse() calls this function each time a value, that is \a input, on the command line needs to be
 validated and subsequently converted to the type of \a argument. A descriptive error message will
 be outputted if \a input cannot be converted to the required type.

 The default implementation uses QVariant::canConvert() and QVariant::convert() for doing conversions.

 QApplicationArgumentParser can be subclassed and this function subsequently overridden, to handle custom types.

 If \a input isn't valid input for \a argument, this function returns a default constructed
 QVariant.

 \sa typeToName(), parse()
 */
QVariant QApplicationArgumentParser::convertToValue(const QApplicationArgument &argument,
                                                    const QString &input) const
{
    const int type = argument.type();

    switch(type)
    {
        case QVariant::Bool:
        {
            if(input == QLatin1String("true") || input == QChar::fromLatin1('1'))
                return QVariant(true);
            else if(input == QLatin1String("false") || input == QChar::fromLatin1('0'))
                return QVariant(false);
            else
                return QApplicationArgumentParserPrivate::conversionError(typeToName(argument), input);
        }
        case QVariant::RegExp:
        {
            QRegExp exp(input);

            if(exp.isValid())
                return QVariant(exp);
            else
                return QApplicationArgumentParserPrivate::conversionError(typeToName(argument), input);
        }
        case QVariant::Url:
        {
            const QUrl result(input);

            if(result.isValid())
                return QVariant(result);
            else
                return QApplicationArgumentParserPrivate::conversionError(typeToName(argument), input);
        }
        default:
        {
            QVariant result(input);

            if(QApplicationArgumentParserPrivate::isBuiltinVariant(type) &&
               result.convert(type))
                return result;
            else
                return QApplicationArgumentParserPrivate::conversionError(typeToName(argument), input);
        }
    }
}

/*!
 This function is only of interest when subclassing.

  convertToValue() calls this function when requiring a string for referring to \a type,
  when generating user messages.

  The implementation uses QMetaType::typeName() for most types, but special handles
  some types, in order to let the message be better tailored for humans.

 \sa convertToValue()
 */
QString QApplicationArgumentParser::typeToName(const QApplicationArgument &argument) const
{
    /* Personally I think nameForType() would be a better name but this is consistent
     * with QVariant's function of the same name. */
    const int type = argument.type();

    switch(type)
    {
        case QVariant::RegExp:
            return QApplicationArgumentParserPrivate::tr("regular expression");
        case QVariant::Url:
            return QLatin1String("URI");
        case QVariant::String:
            return QLatin1String("string");
        default:
        {
            return QString::fromLatin1(QMetaType::typeName(type));
        }
    }
}

/*!
 Returns the default value for \a argument. The default implementation returns
 QApplicationArgument::defaultValue(), if \a argument has been added to this parser.

 Overriding this function can be useful if creating the default value is resource
 consuming, such as opening a file.
 */
QVariant QApplicationArgumentParser::defaultValue(const QApplicationArgument &argument) const
{
    return d->declaredArguments.value(argument.name()).defaultValue();
}

/*!
 Returns the count of how many times \a argument was used on the command line.

 \sa has()
 */
int QApplicationArgumentParser::count(const QApplicationArgument &argument) const
{
    Q_ASSERT_X(d->declaredArguments.contains(argument.name()) ||
               d->declaredNamelessArguments.contains(argument), Q_FUNC_INFO,
               "The argument isn't known to the parser. Has addArgument() been called?");
    return d->count(argument);
}

/*!
 Returns \c true if \a argument has been
 specified one or more times on the command line, otherwise \a false.

 \sa count()
 */
bool QApplicationArgumentParser::has(const QApplicationArgument &argument) const
{
    Q_ASSERT_X(d->declaredArguments.contains(argument.name()) ||
               d->declaredNamelessArguments.contains(argument), Q_FUNC_INFO,
               "The argument isn't known to the parser. Has addArgument() been called?");
    return d->contains(argument);
}

/*!
  // TODO docs

 \sa values()
 */
QVariant QApplicationArgumentParser::value(const QApplicationArgument &argument) const
{
    Q_ASSERT_X(d->declaredArguments.contains(argument.name()) ||
               d->declaredNamelessArguments.contains(argument), Q_FUNC_INFO,
               "The argument isn't known to the parser. Has addArgument() been called?");

    const int len = d->usedArguments.count();

    for(int i = 0; i < len; ++i)
    {
        if(d->usedArguments.at(i).first == argument)
            return d->usedArguments.at(i).second;
    }

    return defaultValue(argument);
}

/*!
  // TODO docs
 \sa value()
 */
QVariantList QApplicationArgumentParser::values(const QApplicationArgument &argument) const
{
    Q_ASSERT_X(d->declaredArguments.contains(argument.name()) ||
               d->declaredNamelessArguments.contains(argument),
               Q_FUNC_INFO,
               "The argument isn't known to the parser. Has addArgument() been called?");

    const int len = d->usedArguments.count();

    QVariantList result;
    for(int i = 0; i < len; ++i)
    {
        if(d->usedArguments.at(i).first == argument)
            result.append(d->usedArguments.at(i).second);
    }

    // TODO how do we handle default values?
    return result;
}

/*!
 After parse() has been called, this function returns a code that can be used to
 exit \c main() with. It returns zero upon success or if help was requested, and
 otherwise a value signalling failure.
 */
QApplicationArgumentParser::ExitCode QApplicationArgumentParser::exitCode() const
{
    return d->exitCode;
}

/*!
 This function is only of interest when subclassing.

 Makes exitCode() return \a code.
 */
void QApplicationArgumentParser::setExitCode(ExitCode code)
{
    d->exitCode = code;
}

/*!
 Sets the application description to \a description.

 The application description is a sentence or two used for help and version
 messages, that briefly describes the application.

 The default is the empty string.
 */
void QApplicationArgumentParser::setApplicationDescription(const QString &description)
{
    d->applicationDescription = description;
}

/*!
 Sets the application version to \a version.

 This string, which is arbitrary but typically is "1.0" or so, is used when
 generating a version statement.
*/
void QApplicationArgumentParser::setApplicationVersion(const QString &version)
{
    d->applicationVersion = version;
}

/*!
 Writes out \a message to \c stderr.
 */
void QApplicationArgumentParser::message(const QString &message) const
{
    d->errorMessage(message);
}

QT_END_NAMESPACE
