/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SK_COMMAND_LINE_FLAGS_H
#define SK_COMMAND_LINE_FLAGS_H

#include "include/core/SkString.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
#include "src/core/SkTHash.h"

/**
 *  Including this file (and compiling CommandLineFlags.cpp) provides command line
 *  parsing. In order to use it, use the following macros in global
 *  namespace:
 *
 *  DEFINE_bool(name, defaultValue, helpString);
 *  DEFINE_string(name, defaultValue, helpString);
 *  DEFINE_int(name, defaultValue, helpString);
 *  DEFINE_double(name, defaultValue, helpString);
 *
 *  Then, in main, call CommandLineFlags::SetUsage() to describe usage and call
 *  CommandLineFlags::Parse() to parse the flags. Henceforth, each flag can
 *  be referenced using
 *
 *  FLAGS_name
 *
 *  For example, the line
 *
 *  DEFINE_bool(boolean, false, "The variable boolean does such and such");
 *
 *  will create the following variable:
 *
 *  bool FLAGS_boolean;
 *
 *  which will initially be set to false, and can be set to true by using the
 *  flag "--boolean" on the commandline. "--noboolean" will set FLAGS_boolean
 *  to false. FLAGS_boolean can also be set using "--boolean=true" or
 *  "--boolean true" (where "true" can be replaced by "false", "TRUE", "FALSE",
 *  "1" or "0").
 *
 *  The helpString will be printed if the help flag (-h or -help) is used.
 *
 *  Similarly, the line
 *
 *  DEFINE_int(integer, .., ..);
 *
 *  will create
 *
 *  int FLAGS_integer;
 *
 *  and
 *
 *  DEFINE_double(real, .., ..);
 *
 *  will create
 *
 *  double FLAGS_real;
 *
 *  These flags can be set by specifying, for example, "--integer 7" and
 *  "--real 3.14" on the command line. Unsigned integers are parsed from the
 *  command line using strtoul() so will detect the base (0 for octal, and
 *  0x or 0X for hex, otherwise assumes decimal).
 *
 *  Unlike the others, the line
 *
 *  DEFINE_string(args, .., ..);
 *
 *  creates an array:
 *
 *  CommandLineFlags::StringArray FLAGS_args;
 *
 *  If the default value is the empty string, FLAGS_args will default to a size
 *  of zero. Otherwise it will default to a size of 1 with the default string
 *  as its value. All strings that follow the flag on the command line (until
 *  a string that begins with '-') will be entries in the array.
 *
 *  DEFINE_extended_string(args, .., .., extendedHelpString);
 *
 *  creates a similar string array flag as DEFINE_string. The flag will have extended help text
 *  (extendedHelpString) that can the user can see with '--help <args>' flag.
 *
 *  Any flag can be referenced from another file after using the following:
 *
 *  DECLARE_x(name);
 *
 *  (where 'x' is the type specified in the DEFINE).
 *
 *  Inspired by gflags (https://code.google.com/p/gflags/). Is not quite as
 *  robust as gflags, but suits our purposes. For example, allows creating
 *  a flag -h or -help which will never be used, since CommandLineFlags handles it.
 *  CommandLineFlags will also allow creating --flag and --noflag. Uses the same input
 *  format as gflags and creates similarly named variables (i.e. FLAGS_name).
 *  Strings are handled differently (resulting variable will be an array of
 *  strings) so that a flag can be followed by multiple parameters.
 */

class SkFlagInfo;

class CommandLineFlags {
public:
    /**
     *  Call to set the help message to be displayed. Should be called before
     *  Parse.
     */
    static void SetUsage(const char* usage);

    /**
     *  Call this to display the help message. Should be called after SetUsage.
     */
    static void PrintUsage();

    /**
     *  Call at the beginning of main to parse flags created by DEFINE_x, above.
     *  Must only be called once.
     */
    static void Parse(int argc, const char* const* argv);

    /**
     *  Custom class for holding the arguments for a string flag.
     *  Publicly only has accessors so the strings cannot be modified.
     */
    class StringArray {
    public:
        StringArray() {}
        explicit StringArray(const skia_private::TArray<SkString>& strings) : fStrings(strings) {}
        const char* operator[](int i) const {
            SkASSERT(i >= 0 && i < fStrings.size());
            return fStrings[i].c_str();
        }

        int size() const { return fStrings.size(); }

        bool isEmpty() const { return this->size() == 0; }

        /**
         * Returns true iff string is equal to one of the strings in this array.
         */
        bool contains(const char* string) const {
            for (int i = 0; i < fStrings.size(); i++) {
                if (fStrings[i].equals(string)) {
                    return true;
                }
            }
            return false;
        }

        void set(int i, const char* str) {
            if (i >= fStrings.size()) {
                this->append(str);
                return;
            }
            fStrings[i].set(str);
        }

        const SkString* begin() const { return fStrings.begin(); }
        const SkString* end() const { return fStrings.end(); }

        /**
         * Parses and validates a string flag that requires exactly one value out of a set of
         * possible values. Returns a non-empty message in the case of errors.
         */
        template <class E>
        SkString parseAndValidate(const char* name,
                                  const skia_private::THashMap<SkString, E>& possibleValues,
                                  E* out) const {
            if (size() == 0) {
                return SkStringPrintf("Flag %s is required.", name);
            }
            if (size() != 1) {
                return SkStringPrintf("Flag %s takes 1 value, got %d.", name, size());
            }
            E* found = possibleValues.find(SkString(operator[](0)));
            if (found != nullptr) {
                *out = *found;
                return SkString();
            }
            return SkStringPrintf("Unknown value for flag %s: %s.", name, operator[](0));
        }

    private:
        void reset() { fStrings.clear(); }

        void append(const char* string) { fStrings.push_back().set(string); }

        void append(const char* string, size_t length) { fStrings.push_back().set(string, length); }

        skia_private::TArray<SkString> fStrings;

        friend class SkFlagInfo;
    };

    /* Takes a list of the form [~][^]match[$]
     ~ causes a matching test to always be skipped
     ^ requires the start of the test to match
     $ requires the end of the test to match
     ^ and $ requires an exact match
     If a test does not match any list entry, it is skipped unless some list entry starts with ~
    */
    static bool ShouldSkip(const SkTDArray<const char*>& strings, const char* name);
    static bool ShouldSkip(const StringArray& strings, const char* name);

private:
    static SkFlagInfo* gHead;
    static SkString    gUsage;

    // For access to gHead.
    friend class SkFlagInfo;
};

#define TO_STRING2(s) #s
#define TO_STRING(s) TO_STRING2(s)

#define DEFINE_bool(name, defaultValue, helpString)                          \
    bool FLAGS_##name;                                                       \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateBoolFlag( \
            TO_STRING(name), nullptr, &FLAGS_##name, defaultValue, helpString)

// bool 2 allows specifying a short name. No check is done to ensure that shortName
// is actually shorter than name.
#define DEFINE_bool2(name, shortName, defaultValue, helpString)              \
    bool FLAGS_##name;                                                       \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateBoolFlag( \
            TO_STRING(name), TO_STRING(shortName), &FLAGS_##name, defaultValue, helpString)

#define DECLARE_bool(name) extern bool FLAGS_##name;

#define DEFINE_string(name, defaultValue, helpString)                          \
    CommandLineFlags::StringArray FLAGS_##name;                                \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateStringFlag( \
            TO_STRING(name), nullptr, &FLAGS_##name, defaultValue, helpString, nullptr)
#define DEFINE_extended_string(name, defaultValue, helpString, extendedHelpString) \
    CommandLineFlags::StringArray FLAGS_##name;                                    \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateStringFlag(     \
            TO_STRING(name), nullptr, &FLAGS_##name, defaultValue, helpString, extendedHelpString)

// string2 allows specifying a short name. There is an assert that shortName
// is only 1 character.
#define DEFINE_string2(name, shortName, defaultValue, helpString)                                  \
    CommandLineFlags::StringArray FLAGS_##name;                                                    \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name),     \
                                                                              TO_STRING(shortName),\
                                                                              &FLAGS_##name,       \
                                                                              defaultValue,        \
                                                                              helpString,          \
                                                                              nullptr)

#define DECLARE_string(name) extern CommandLineFlags::StringArray FLAGS_##name;

#define DEFINE_int(name, defaultValue, helpString) \
    int FLAGS_##name;                              \
    [[maybe_unused]] static bool unused_##name =   \
            SkFlagInfo::CreateIntFlag(TO_STRING(name), &FLAGS_##name, defaultValue, helpString)

#define DEFINE_int_2(name, shortName, defaultValue, helpString)             \
    int FLAGS_##name;                                                       \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateIntFlag( \
            TO_STRING(name), TO_STRING(shortName), &FLAGS_##name, defaultValue, helpString)

#define DECLARE_int(name) extern int FLAGS_##name;

#define DEFINE_double(name, defaultValue, helpString) \
    double FLAGS_##name;                              \
    [[maybe_unused]] static bool unused_##name =      \
            SkFlagInfo::CreateDoubleFlag(TO_STRING(name), &FLAGS_##name, defaultValue, helpString)

#define DECLARE_double(name) extern double FLAGS_##name;

class SkFlagInfo {
public:
    enum FlagTypes {
        kBool_FlagType,
        kString_FlagType,
        kInt_FlagType,
        kDouble_FlagType,
    };

    /**
     *  Each Create<Type>Flag function creates an SkFlagInfo of the specified type. The SkFlagInfo
     *  object is appended to a list, which is deleted when CommandLineFlags::Parse is called.
     *  Therefore, each call should be made before the call to ::Parse. They are not intended
     *  to be called directly. Instead, use the macros described above.
     *  @param name Long version (at least 2 characters) of the name of the flag. This name can
     *      be referenced on the command line as "--name" to set the value of this flag.
     *  @param shortName Short version (one character) of the name of the flag. This name can
     *      be referenced on the command line as "-shortName" to set the value of this flag.
     *  @param p<Type> Pointer to a global variable which holds the value set by CommandLineFlags.
     *  @param defaultValue The default value of this flag. The variable pointed to by p<Type> will
     *      be set to this value initially. This is also displayed as part of the help output.
     *  @param helpString Explanation of what this flag changes in the program.
     */
    static bool CreateBoolFlag(const char* name,
                               const char* shortName,
                               bool*       pBool,
                               bool        defaultValue,
                               const char* helpString) {
        SkFlagInfo* info  = new SkFlagInfo(name, shortName, kBool_FlagType, helpString, nullptr);
        info->fBoolValue  = pBool;
        *info->fBoolValue = info->fDefaultBool = defaultValue;
        return true;
    }

    /**
     *  See comments for CreateBoolFlag.
     *  @param pStrings Unlike the others, this is a pointer to an array of values.
     *  @param defaultValue Thise default will be parsed so that strings separated by spaces
     *      will be added to pStrings.
     */
    static bool CreateStringFlag(const char*                    name,
                                 const char*                    shortName,
                                 CommandLineFlags::StringArray* pStrings,
                                 const char*                    defaultValue,
                                 const char*                    helpString,
                                 const char*                    extendedHelpString);

    /**
     *  See comments for CreateBoolFlag.
     */
    static bool CreateIntFlag(const char* name,
                              int*    pInt,
                              int     defaultValue,
                              const char* helpString) {
        SkFlagInfo* info = new SkFlagInfo(name, nullptr, kInt_FlagType, helpString, nullptr);
        info->fIntValue  = pInt;
        *info->fIntValue = info->fDefaultInt = defaultValue;
        return true;
    }

    static bool CreateIntFlag(const char* name,
                              const char* shortName,
                              int*    pInt,
                              int     defaultValue,
                              const char* helpString) {
        SkFlagInfo* info = new SkFlagInfo(name, shortName, kInt_FlagType, helpString, nullptr);
        info->fIntValue  = pInt;
        *info->fIntValue = info->fDefaultInt = defaultValue;
        return true;
    }

    /**
     *  See comments for CreateBoolFlag.
     */
    static bool CreateDoubleFlag(const char* name,
                                 double*     pDouble,
                                 double      defaultValue,
                                 const char* helpString) {
        SkFlagInfo* info    = new SkFlagInfo(name, nullptr, kDouble_FlagType, helpString, nullptr);
        info->fDoubleValue  = pDouble;
        *info->fDoubleValue = info->fDefaultDouble = defaultValue;
        return true;
    }

    /**
     *  Returns true if the string matches this flag.
     *  For a boolean flag, also sets the value, since a boolean flag can be set in a number of ways
     *  without looking at the following string:
     *      --name
     *      --noname
     *      --name=true
     *      --name=false
     *      --name=1
     *      --name=0
     *      --name=TRUE
     *      --name=FALSE
     */
    bool match(const char* string);

    FlagTypes getFlagType() const { return fFlagType; }

    void resetStrings() {
        if (kString_FlagType == fFlagType) {
            fStrings->reset();
        } else {
            SkDEBUGFAIL("Can only call resetStrings on kString_FlagType");
        }
    }

    void append(const char* string) {
        if (kString_FlagType == fFlagType) {
            fStrings->append(string);
        } else {
            SkDEBUGFAIL("Can only append to kString_FlagType");
        }
    }

    void setInt(int value) {
        if (kInt_FlagType == fFlagType) {
            *fIntValue = value;
        } else {
            SkDEBUGFAIL("Can only call setInt on kInt_FlagType");
        }
    }

    void setDouble(double value) {
        if (kDouble_FlagType == fFlagType) {
            *fDoubleValue = value;
        } else {
            SkDEBUGFAIL("Can only call setDouble on kDouble_FlagType");
        }
    }

    void setBool(bool value) {
        if (kBool_FlagType == fFlagType) {
            *fBoolValue = value;
        } else {
            SkDEBUGFAIL("Can only call setBool on kBool_FlagType");
        }
    }

    SkFlagInfo* next() { return fNext; }

    const SkString& name() const { return fName; }

    const SkString& shortName() const { return fShortName; }

    const SkString& help() const { return fHelpString; }
    const SkString& extendedHelp() const { return fExtendedHelpString; }

    SkString defaultValue() const {
        SkString result;
        switch (fFlagType) {
            case SkFlagInfo::kBool_FlagType:
                result.printf("%s", fDefaultBool ? "true" : "false");
                break;
            case SkFlagInfo::kString_FlagType: return fDefaultString;
            case SkFlagInfo::kInt_FlagType: result.printf("%i", fDefaultInt); break;
            case SkFlagInfo::kDouble_FlagType: result.printf("%2.2f", fDefaultDouble); break;
            default: SkDEBUGFAIL("Invalid flag type");
        }
        return result;
    }

    SkString typeAsString() const {
        switch (fFlagType) {
            case SkFlagInfo::kBool_FlagType: return SkString("bool");
            case SkFlagInfo::kString_FlagType: return SkString("string");
            case SkFlagInfo::kInt_FlagType: return SkString("int");
            case SkFlagInfo::kDouble_FlagType: return SkString("double");
            default: SkDEBUGFAIL("Invalid flag type"); return SkString();
        }
    }

private:
    SkFlagInfo(const char* name,
               const char* shortName,
               FlagTypes   type,
               const char* helpString,
               const char* extendedHelpString)
            : fName(name)
            , fShortName(shortName)
            , fFlagType(type)
            , fHelpString(helpString)
            , fExtendedHelpString(extendedHelpString)
            , fBoolValue(nullptr)
            , fDefaultBool(false)
            , fIntValue(nullptr)
            , fDefaultInt(0)
            , fDoubleValue(nullptr)
            , fDefaultDouble(0)
            , fStrings(nullptr) {
        fNext                   = CommandLineFlags::gHead;
        CommandLineFlags::gHead = this;
        SkASSERT(name && strlen(name) > 1);
        SkASSERT(nullptr == shortName || 1 == strlen(shortName));
    }

    /**
     *  Set a StringArray to hold the values stored in defaultStrings.
     *  @param array The StringArray to modify.
     *  @param defaultStrings Space separated list of strings that should be inserted into array
     *      individually.
     */
    static void SetDefaultStrings(CommandLineFlags::StringArray* array, const char* defaultStrings);

    // Name of the flag, without initial dashes
    SkString                       fName;
    SkString                       fShortName;
    FlagTypes                      fFlagType;
    SkString                       fHelpString;
    SkString                       fExtendedHelpString;
    bool*                          fBoolValue;
    bool                           fDefaultBool;
    int*                           fIntValue;
    int                            fDefaultInt;
    double*                        fDoubleValue;
    double                         fDefaultDouble;
    CommandLineFlags::StringArray* fStrings;
    // Both for the help string and in case fStrings is empty.
    SkString fDefaultString;

    // In order to keep a linked list.
    SkFlagInfo* fNext;
};
#endif  // SK_COMMAND_LINE_FLAGS_H
