/*
 * 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 "../private/SkTArray.h"
#include "../private/SkTDArray.h"
#include "SkString.h"

/**
 *  Including this file (and compiling SkCommandLineFlags.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_int32(name, defaultValue, helpString);
 *  DEFINE_double(name, defaultValue, helpString);
 *
 *  Then, in main, call SkCommandLineFlags::SetUsage() to describe usage and call
 *  SkCommandLineFlags::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_int32(integer, .., ..);
 *
 *  will create
 *
 *  int32_t 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.
 *
 *  Unlike the others, the line
 *
 *  DEFINE_string(args, .., ..);
 *
 *  creates an array:
 *
 *  SkCommandLineFlags::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 SkCommandLineFlags handles it.
 *  SkCommandLineFlags 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 SkCommandLineFlags {

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, char** 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 SkTArray<SkString>& strings)
            : fStrings(strings) {
        }
        const char* operator[](int i) const {
            SkASSERT(i >= 0 && i < fStrings.count());
            return fStrings[i].c_str();
        }

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

        bool isEmpty() const { return this->count() == 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.count(); i++) {
                if (fStrings[i].equals(string)) {
                    return true;
                }
            }
            return false;
        }

        void set(int i, const char* str) {
            fStrings[i].set(str);
        }

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

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

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

        SkTArray<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;                                                          \
SK_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;                                                          \
SK_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)                       \
SkCommandLineFlags::StringArray FLAGS_##name;                               \
SK_UNUSED static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name),   \
                                                                   nullptr,              \
                                                                   &FLAGS_##name,     \
                                                                   defaultValue,      \
                                                                   helpString, nullptr)
#define DEFINE_extended_string(name, defaultValue, helpString, extendedHelpString) \
SkCommandLineFlags::StringArray FLAGS_##name;                                      \
SK_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)               \
SkCommandLineFlags::StringArray FLAGS_##name;                                   \
SK_UNUSED static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name),       \
                                                                   TO_STRING(shortName),  \
                                                                   &FLAGS_##name,         \
                                                                   defaultValue,          \
                                                                   helpString, nullptr)

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




#define DEFINE_int32(name, defaultValue, helpString)                        \
int32_t FLAGS_##name;                                                       \
SK_UNUSED static bool unused_##name = SkFlagInfo::CreateIntFlag(TO_STRING(name),      \
                                                                &FLAGS_##name,        \
                                                                defaultValue,         \
                                                                helpString)

#define DEFINE_int32_2(name, shortName, defaultValue, helpString)                     \
int32_t FLAGS_##name;                                                                 \
SK_UNUSED static bool unused_##name = SkFlagInfo::CreateIntFlag(TO_STRING(name),      \
                                                                TO_STRING(shortName), \
                                                                &FLAGS_##name,        \
                                                                defaultValue,         \
                                                                helpString)

#define DECLARE_int32(name) extern int32_t FLAGS_##name;

#define DEFINE_double(name, defaultValue, helpString)                       \
double FLAGS_##name;                                                        \
SK_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 SkCommandLineFlags::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 SkCommandLineFlags.
     *  @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,
                                 SkCommandLineFlags::StringArray* pStrings,
                                 const char* defaultValue, const char* helpString,
                                 const char* extendedHelpString);

    /**
     *  See comments for CreateBoolFlag.
     */
    static bool CreateIntFlag(const char* name, int32_t* pInt,
                              int32_t 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, int32_t* pInt,
                              int32_t 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(int32_t 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 = SkCommandLineFlags::gHead;
        SkCommandLineFlags::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(SkCommandLineFlags::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;
    int32_t*             fIntValue;
    int32_t              fDefaultInt;
    double*              fDoubleValue;
    double               fDefaultDouble;
    SkCommandLineFlags::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
