// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/439062058): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "dawn/utils/CommandLineParser.h"

#include <algorithm>
#include <tuple>

#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"

namespace dawn::utils {

// OptionBase

CommandLineParser::OptionBase::OptionBase(absl::string_view name, absl::string_view desc)
    : mName(name), mDescription(desc), mParameter("value") {}

CommandLineParser::OptionBase::~OptionBase() = default;

const std::string& CommandLineParser::OptionBase::GetName() const {
    return mName;
}

std::string CommandLineParser::OptionBase::GetShortName() const {
    return mShortName;
}

const std::string& CommandLineParser::OptionBase::GetDescription() const {
    return mDescription;
}

std::string CommandLineParser::OptionBase::GetParameter() const {
    return mParameter;
}

bool CommandLineParser::OptionBase::IsSet() const {
    return mSet;
}

CommandLineParser::OptionBase::ParseResult CommandLineParser::OptionBase::Parse(
    absl::Span<const absl::string_view> args) {
    auto result = ParseImpl(args);
    if (result.success) {
        mSet = true;
    }
    return result;
}

// BoolOption

CommandLineParser::BoolOption::BoolOption(absl::string_view name, absl::string_view desc)
    : Option(name, desc) {}

CommandLineParser::BoolOption::~BoolOption() = default;

bool CommandLineParser::BoolOption::GetValue() const {
    return mValue;
}

std::string CommandLineParser::BoolOption::GetParameter() const {
    return {};
}

CommandLineParser::OptionBase::ParseResult CommandLineParser::BoolOption::ParseImpl(
    absl::Span<const absl::string_view> args) {
    // Explicit true
    if (!args.empty() && args.front() == "true") {
        if (IsSet()) {
            return {false, args, "cannot set multiple times with explicit true/false arguments"};
        }

        mValue = true;
        return {true, args.subspan(1)};
    }

    // Explicit false
    if (!args.empty() && args.front() == "false") {
        if (IsSet()) {
            return {false, args, "cannot set multiple times with explicit true/false arguments"};
        }

        mValue = false;
        return {true, args.subspan(1)};
    }

    // Assuming --option just means to set it to true. Allow setting the option multiple times
    // to true with this form.
    if (IsSet() && !mValue) {
        return {false, args, "cannot be set to both true and false"};
    }

    mValue = true;
    return {true, args};
}

// StringOption

CommandLineParser::StringOption::StringOption(absl::string_view name, absl::string_view desc)
    : Option(name, desc) {}

CommandLineParser::StringOption::~StringOption() = default;

std::string CommandLineParser::StringOption::GetValue() const {
    return mValue;
}

CommandLineParser::OptionBase::ParseResult CommandLineParser::StringOption::ParseImpl(
    absl::Span<const absl::string_view> args) {
    if (IsSet()) {
        return {false, args, "cannot be set multiple times"};
    }

    if (args.empty()) {
        return {false, args, "expected a value"};
    }

    mValue = args.front();
    return {true, args.subspan(1)};
}

// StringListOption

CommandLineParser::StringListOption::StringListOption(absl::string_view name,
                                                      absl::string_view desc)
    : Option(name, desc) {}

CommandLineParser::StringListOption::~StringListOption() = default;

absl::Span<const std::string> CommandLineParser::StringListOption::GetValue() const {
    return mValue;
}

std::vector<std::string> CommandLineParser::StringListOption::GetOwnedValue() const {
    std::vector<std::string> result;
    for (auto& v : mValue) {
        result.push_back(v);
    }
    return result;
}

CommandLineParser::OptionBase::ParseResult CommandLineParser::StringListOption::ParseImpl(
    absl::Span<const absl::string_view> args) {
    if (args.empty()) {
        return {false, args, "expected a value"};
    }

    for (absl::string_view s : absl::StrSplit(args.front(), ",")) {
        mValue.push_back(std::string{s});
    }
    return {true, args.subspan(1)};
}

// CommandLineParser

CommandLineParser::BoolOption& CommandLineParser::AddBool(absl::string_view name,
                                                          absl::string_view desc) {
    return AddOption(std::make_unique<BoolOption>(name, desc));
}

CommandLineParser::StringOption& CommandLineParser::AddString(absl::string_view name,
                                                              absl::string_view desc) {
    return AddOption(std::make_unique<StringOption>(name, desc));
}

CommandLineParser::StringListOption& CommandLineParser::AddStringList(absl::string_view name,
                                                                      absl::string_view desc) {
    return AddOption(std::make_unique<StringListOption>(name, desc));
}

// static
std::string CommandLineParser::JoinConversionNames(absl::Span<const absl::string_view> names,
                                                   absl::string_view separator) {
    return absl::StrJoin(names, separator);
}

CommandLineParser::BoolOption& CommandLineParser::AddHelp() {
    return AddBool("help", "Shows the help").ShortName('h');
}

// static
const CommandLineParser::ParseOptions CommandLineParser::kDefaultParseOptions = {};

CommandLineParser::ParseResult CommandLineParser::Parse(absl::Span<const absl::string_view> args,
                                                        const ParseOptions& parseOptions) {
    // Build the map of name to option.
    absl::flat_hash_map<std::string, OptionBase*> nameToOption;

    for (auto& option : mOptions) {
        if (!nameToOption.emplace(option->GetName(), option.get()).second) {
            return {false,
                    absl::StrFormat("Duplicate options with name \"%s\"", option->GetName())};
        }

        if (!option->GetShortName().empty() &&
            !nameToOption.emplace(option->GetShortName(), option.get()).second) {
            return {false,
                    absl::StrFormat("Duplicate options with name \"%s\"", option->GetShortName())};
        }
    }

    auto nextArgs = args;
    while (!nextArgs.empty()) {
        auto arg = nextArgs.front();
        nextArgs = nextArgs.subspan(1);

        // Skip or error if it is not an option.
        if (arg.empty() || arg[0] != '-') {
            if (parseOptions.unknownIsError) {
                return {false, absl::StrFormat("Unknown option \"%s\"", arg)};
            }
            continue;
        }

        // Remove starting - or --
        arg = arg.substr(1);
        if (!arg.empty() && arg[0] == '-') {
            arg = arg.substr(1);
        }

        // Split at the = if there is one and use the right side as the option's arguments
        if (auto equalPos = arg.find('='); equalPos != std::string::npos) {
            auto name = arg.substr(0, equalPos);
            auto rest = arg.substr(equalPos + 1);

            // Skip or error if it is an unknown option.
            if (!nameToOption.contains(name)) {
                if (parseOptions.unknownIsError) {
                    return {false, absl::StrFormat("Unknown option \"%s\"", name)};
                }
                continue;
            }

            auto option = nameToOption[name];
            auto optionResult = option->Parse({&rest, 1});
            if (!optionResult.success) {
                return {false, absl::StrFormat("Failure while parsing \"%s\": %s",
                                               option->GetName(), optionResult.errorMessage)};
            }
            if (!optionResult.remainingArgs.empty()) {
                return {false, absl::StrFormat("Argument \"%s\" was not valid for option \"%s\"",
                                               rest, option->GetName())};
            }
            continue;
        }

        // Otherwise make the option greedily parse from the rest of the command line.
        // Skip or error if it is an unknown option.
        if (!nameToOption.contains(arg)) {
            if (parseOptions.unknownIsError) {
                return {false, absl::StrFormat("Unknown option \"%s\"", arg)};
            }
            continue;
        }

        // Try to parse the arg.
        auto option = nameToOption[arg];
        auto optionResult = option->Parse(nextArgs);
        if (!optionResult.success) {
            return {false, absl::StrFormat("Failure while parsing \"%s\": %s", option->GetName(),
                                           optionResult.errorMessage)};
        }
        nextArgs = optionResult.remainingArgs;
    }

    return {true};
}

CommandLineParser::ParseResult CommandLineParser::Parse(const std::vector<std::string>& args,
                                                        const ParseOptions& parseOptions) {
    std::vector<absl::string_view> viewArgs;
    for (const auto& arg : args) {
        viewArgs.push_back(arg);
    }

    return Parse(viewArgs, parseOptions);
}

CommandLineParser::ParseResult CommandLineParser::Parse(int argc,
                                                        const char** argv,
                                                        const ParseOptions& parseOptions) {
    std::vector<absl::string_view> args;
    for (int i = 1; i < argc; i++) {
        args.push_back(argv[i]);
    }

    return Parse(args, parseOptions);
}

void CommandLineParser::PrintHelp(std::ostream& s) {
    // Sort options in alphabetical order using a trick that std::tuple is sorted lexicographically.
    std::vector<std::tuple<absl::string_view, OptionBase*>> sortedOptions;
    for (auto& option : mOptions) {
        sortedOptions.emplace_back(option->GetName(), option.get());
    }
    std::sort(sortedOptions.begin(), sortedOptions.end());

    for (auto& [name, option] : sortedOptions) {
        s << "--" << name;

        std::string parameter = option->GetParameter();
        if (!parameter.empty()) {
            s << " <" << parameter << ">";
        }

        const auto& desc = option->GetDescription();
        if (!desc.empty()) {
            s << "  " << desc;
        }

        s << "\n";

        if (!option->GetShortName().empty()) {
            s << "-" << option->GetShortName() << "  alias for --" << name << "\n";
        }
    }
}

}  // namespace dawn::utils
