/*
 * 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/SkMacros.h"
#include "include/private/SkTArray.h"
#include "include/private/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 DEFINE_bool(name, defaultValue, helpString)                          \
    bool FLAGS_##name;                                                       \
    [[maybe_unused]] static bool unused_##name = SkFlagInfo::CreateBoolFlag( \
            SK_MACRO_STRINGIFY(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(SK_MACRO_STRINGIFY(name),      \
                                       SK_MACRO_STRINGIFY(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( \
            SK_MACRO_STRINGIFY(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(SK_MACRO_STRINGIFY(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(SK_MACRO_STRINGIFY(name),      \
                                         SK_MACRO_STRINGIFY(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( \
            SK_MACRO_STRINGIFY(name), &FLAGS_##name, defaultValue, helpString)

#define DEFINE_int_2(name, shortName, defaultValue, helpString)      \
    int FLAGS_##name;                                                \
    [[maybe_unused]] static bool unused_##name =                     \
            SkFlagInfo::CreateIntFlag(SK_MACRO_STRINGIFY(name),      \
                                      SK_MACRO_STRINGIFY(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( \
            SK_MACRO_STRINGIFY(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
