// Copyright 2023 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_TINT_UTILS_CLI_H_
#define SRC_TINT_UTILS_CLI_H_

#include <deque>
#include <optional>
#include <string>
#include <utility>

#include "src/tint/utils/block_allocator.h"
#include "src/tint/utils/compiler_macros.h"
#include "src/tint/utils/parse_num.h"
#include "src/tint/utils/result.h"
#include "src/tint/utils/string.h"
#include "src/tint/utils/vector.h"

namespace tint::utils::cli {

/// Alias is a fluent-constructor helper for Options
struct Alias {
    /// The alias to apply to an Option
    std::string value;

    /// @param option the option to apply the alias to
    template <typename T>
    void Apply(T& option) {
        option.alias = value;
    }
};

/// ShortName is a fluent-constructor helper for Options
struct ShortName {
    /// The short-name to apply to an Option
    std::string value;

    /// @param option the option to apply the short name to
    template <typename T>
    void Apply(T& option) {
        option.short_name = value;
    }
};

/// Parameter is a fluent-constructor helper for Options
struct Parameter {
    /// The parameter name to apply to an Option
    std::string value;

    /// @param option the option to apply the parameter name to
    template <typename T>
    void Apply(T& option) {
        option.parameter = value;
    }
};

/// Default is a fluent-constructor helper for Options
template <typename T>
struct Default {
    /// The default value to apply to an Option
    T value;

    /// @param option the option to apply the default value to
    template <typename O>
    void Apply(O& option) {
        option.default_value = value;
    }
};

/// Deduction guide for Default
template <typename T>
Default(T) -> Default<T>;

/// Option is the base class for all command line options
class Option {
  public:
    /// An alias to std::string, used to hold error messages.
    using Error = std::string;

    /// Destructor
    virtual ~Option();

    /// @return the name of the option, without any leading hyphens.
    /// Example: 'help'
    virtual std::string Name() const = 0;

    /// @return the alias name of the option, without any leading hyphens. (optional)
    /// Example: 'flag'
    virtual std::string Alias() const = 0;

    /// @return the shorter name of the option, without any leading hyphens. (optional)
    /// Example: 'h'
    virtual std::string ShortName() const = 0;

    /// @return a string describing the parameter that the option expects.
    /// Empty represents no expected parameter.
    virtual std::string Parameter() const = 0;

    /// @return a description of the option.
    /// Example: 'shows this message'
    virtual std::string Description() const = 0;

    /// @return the default value of the option, or an empty string if there is no default value.
    virtual std::string DefaultValue() const = 0;

    /// Sets the option value to the default (called before arguments are parsed)
    virtual void SetDefault() = 0;

    /// Parses the option's arguments from the list of command line arguments, removing the consumed
    /// arguments before returning. @p arguments will have already had the option's name consumed
    /// before calling.
    /// @param arguments the queue of unprocessed arguments. Parse() may take from the front of @p
    /// arguments.
    /// @return empty Error if successfully parsed, otherwise an error string.
    virtual Error Parse(std::deque<std::string_view>& arguments) = 0;

  protected:
    /// An empty string, used to represent no-error.
    static constexpr const char* Success = "";

    /// @param expected the expected value(s) for the option
    /// @return an Error message for a missing argument
    Error ErrMissingArgument(std::string expected) const {
        Error err = "missing value for option '--" + Name() + "'";
        if (!expected.empty()) {
            err += "Expected: " + expected;
        }
        return err;
    }

    /// @param got the argument value provided
    /// @param reason the reason the argument is invalid (optional)
    /// @return an Error message for an invalid argument
    Error ErrInvalidArgument(std::string_view got, std::string reason) const {
        Error err = "invalid value '" + std::string(got) + "' for option '--" + Name() + "'";
        if (!reason.empty()) {
            err += "\n" + reason;
        }
        return err;
    }
};

/// OptionSet is a set of Options, which can parse the command line arguments.
class OptionSet {
  public:
    /// Unconsumed is a list of unconsumed command line arguments
    using Unconsumed = utils::Vector<std::string_view, 8>;

    /// Constructs and returns a new Option to be owned by the OptionSet
    /// @tparam T the Option type
    /// @tparam ARGS the constructor argument types
    /// @param args the constructor arguments
    /// @return the constructed Option
    template <typename T, typename... ARGS>
    T& Add(ARGS&&... args) {
        return *options.Create<T>(std::forward<ARGS>(args)...);
    }

    /// Prints to @p out the description of all the command line options.
    /// @param out the output stream
    void ShowHelp(std::ostream& out);

    /// Parses all the options in @p options.
    /// @param err the error stream
    /// @param arguments the command line arguments, excluding the initial executable name
    /// @return a Result holding a list of arguments that were not consumed as options
    Result<Unconsumed> Parse(std::ostream& err, utils::VectorRef<std::string_view> arguments);

  private:
    /// The list of options to parse
    utils::BlockAllocator<Option, 1024> options;
};

/// ValueOption is an option that accepts a single value
template <typename T>
class ValueOption : public Option {
    static constexpr bool is_bool = std::is_same_v<T, bool>;
    static constexpr bool is_number =
        !is_bool && (std::is_integral_v<T> || std::is_floating_point_v<T>);
    static constexpr bool is_string = std::is_same_v<T, std::string>;
    static_assert(is_bool || is_number || is_string, "unsupported data type");

  public:
    /// The name of the option, without any leading hyphens.
    std::string name;
    /// The alias name of the option, without any leading hyphens.
    std::string alias;
    /// The shorter name of the option, without any leading hyphens.
    std::string short_name;
    /// A description of the option.
    std::string description;
    /// The default value.
    std::optional<T> default_value;
    /// The option value. Populated with Parse().
    std::optional<T> value;
    /// A string describing the name of the option's value.
    std::string parameter = "value";

    /// Constructor
    ValueOption() = default;

    /// Constructor
    /// @param option_name the option name
    /// @param option_description the option description
    /// @param settings a number of fluent-constructor values that configure the option
    /// @see ShortName, Parameter, Default
    template <typename... SETTINGS>
    ValueOption(std::string option_name, std::string option_description, SETTINGS&&... settings)
        : name(std::move(option_name)), description(std::move(option_description)) {
        (settings.Apply(*this), ...);
    }

    std::string Name() const override { return name; }

    std::string Alias() const override { return alias; }

    std::string ShortName() const override { return short_name; }

    std::string Parameter() const override { return parameter; }

    std::string Description() const override { return description; }

    std::string DefaultValue() const override {
        return default_value.has_value() ? ToString(*default_value) : "";
    }

    void SetDefault() override { value = default_value; }

    Error Parse(std::deque<std::string_view>& arguments) override {
        TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE);

        if (arguments.empty()) {
            if constexpr (is_bool) {
                // Treat as flag (--blah)
                value = true;
                return Success;
            } else {
                return ErrMissingArgument(parameter);
            }
        }

        auto arg = arguments.front();

        if constexpr (is_number) {
            auto result = ParseNumber<T>(arg);
            if (result) {
                value = result.Get();
                arguments.pop_front();
                return Success;
            }
            if (result.Failure() == ParseNumberError::kResultOutOfRange) {
                return ErrInvalidArgument(arg, "value out of range");
            }
            return ErrInvalidArgument(arg, "failed to parse value");
        } else if constexpr (is_string) {
            value = arg;
            arguments.pop_front();
            return Success;
        } else if constexpr (is_bool) {
            if (arg == "true") {
                value = true;
                arguments.pop_front();
                return Success;
            }
            if (arg == "false") {
                value = false;
                arguments.pop_front();
                return Success;
            }
            // Next argument is assumed to be another option, or unconsumed argument.
            // Treat as flag (--blah)
            value = true;
            return Success;
        }

        TINT_END_DISABLE_WARNING(UNREACHABLE_CODE);
    }
};

/// BoolOption is an alias to ValueOption<bool>
using BoolOption = ValueOption<bool>;

/// StringOption is an alias to ValueOption<std::string>
using StringOption = ValueOption<std::string>;

/// EnumName is a pair of enum value and name.
/// @tparam ENUM the enum type
template <typename ENUM>
struct EnumName {
    /// Constructor
    EnumName() = default;

    /// Constructor
    /// @param v the enum value
    /// @param n the name of the enum value
    EnumName(ENUM v, std::string n) : value(v), name(std::move(n)) {}

    /// the enum value
    ENUM value;
    /// the name of the enum value
    std::string name;
};

/// Deduction guide for EnumName
template <typename ENUM>
EnumName(ENUM, std::string) -> EnumName<ENUM>;

/// EnumOption is an option that accepts an enumerator of values
template <typename ENUM>
class EnumOption : public Option {
  public:
    /// The name of the option, without any leading hyphens.
    std::string name;
    /// The alias name of the option, without any leading hyphens.
    std::string alias;
    /// The shorter name of the option, without any leading hyphens.
    std::string short_name;
    /// A description of the option.
    std::string description;
    /// The enum options as a pair of enum value to name
    utils::Vector<EnumName<ENUM>, 8> enum_names;
    /// The default value.
    std::optional<ENUM> default_value;
    /// The option value. Populated with Parse().
    std::optional<ENUM> value;

    /// Constructor
    EnumOption() = default;

    /// Constructor
    /// @param option_name the option name
    /// @param option_description the option description
    /// @param names The enum options as a pair of enum value to name
    /// @param settings a number of fluent-constructor values that configure the option
    /// @see ShortName, Parameter, Default
    template <typename... SETTINGS>
    EnumOption(std::string option_name,
               std::string option_description,
               utils::VectorRef<EnumName<ENUM>> names,
               SETTINGS&&... settings)
        : name(std::move(option_name)),
          description(std::move(option_description)),
          enum_names(std::move(names)) {
        (settings.Apply(*this), ...);
    }

    std::string Name() const override { return name; }

    std::string ShortName() const override { return short_name; }

    std::string Alias() const override { return alias; }

    std::string Parameter() const override { return PossibleValues("|"); }

    std::string Description() const override { return description; }

    std::string DefaultValue() const override {
        for (auto& enum_name : enum_names) {
            if (enum_name.value == default_value) {
                return enum_name.name;
            }
        }
        return "";
    }

    void SetDefault() override { value = default_value; }

    Error Parse(std::deque<std::string_view>& arguments) override {
        if (arguments.empty()) {
            return ErrMissingArgument("one of: " + PossibleValues(", "));
        }
        auto& arg = arguments.front();
        for (auto& enum_name : enum_names) {
            if (enum_name.name == arg) {
                value = enum_name.value;
                arguments.pop_front();
                return Success;
            }
        }
        return ErrInvalidArgument(arg, "Must be one of: " + PossibleValues(", "));
    }

    /// @param delimiter the delimiter between each enum option
    /// @returns the accepted enum names delimited with @p delimiter
    std::string PossibleValues(std::string delimiter) const {
        std::string out;
        for (auto& enum_name : enum_names) {
            if (!out.empty()) {
                out += delimiter;
            }
            out += enum_name.name;
        }
        return out;
    }
};

}  // namespace tint::utils::cli

#endif  // SRC_TINT_UTILS_CLI_H_
