// 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.

#include <fstream>
#include <iostream>
#include <memory>
#include <string>

#include "src/tint/api/tint.h"
#include "src/tint/cmd/common/helper.h"
#include "src/tint/lang/core/ir/binary/decode.h"
#include "src/tint/lang/core/ir/disassembler.h"
#include "src/tint/lang/spirv/writer/writer.h"
#include "src/tint/lang/wgsl/writer/writer.h"
#include "src/tint/utils/cli/cli.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/text/color_mode.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/styled_text_printer.h"

#include "spirv-tools/libspirv.hpp"

TINT_BEGIN_DISABLE_PROTOBUF_WARNINGS();
#include "src/tint/utils/protos/ir_fuzz/ir_fuzz.pb.h"
TINT_END_DISABLE_PROTOBUF_WARNINGS();

namespace {

/// @param data spriv shader to be converted
/// @returns human readable text representation of a SPIR-V shader
tint::Result<std::string> DisassembleSpv(const std::vector<uint32_t>& data) {
    std::string spv_errors;
    spv_target_env target_env = SPV_ENV_VULKAN_1_1;

    auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
                                      const spv_position_t& position, const char* message) {
        switch (level) {
            case SPV_MSG_FATAL:
            case SPV_MSG_INTERNAL_ERROR:
            case SPV_MSG_ERROR:
                spv_errors +=
                    "error: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_WARNING:
                spv_errors +=
                    "warning: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_INFO:
                spv_errors +=
                    "info: line " + std::to_string(position.index) + ": " + message + "\n";
                break;
            case SPV_MSG_DEBUG:
                break;
        }
    };

    spvtools::SpirvTools tools(target_env);
    tools.SetMessageConsumer(msg_consumer);

    std::string result;
    if (!tools.Disassemble(
            data, &result,
            SPV_BINARY_TO_TEXT_OPTION_INDENT | SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES)) {
        return tint::Failure(spv_errors);
    }

    return result;
}

enum class Format : uint8_t {
    kUnknown,
    kSpirv,
    kSpvAsm,
    kWgsl,
};

/// @param filename the filename to inspect
/// @returns the inferred format for the filename suffix
Format InferFormat(const std::string& filename) {
    if (tint::HasSuffix(filename, ".spv")) {
        return Format::kSpirv;
    }
    if (tint::HasSuffix(filename, ".spvasm")) {
        return Format::kSpvAsm;
    }

    if (tint::HasSuffix(filename, ".wgsl")) {
        return Format::kWgsl;
    }

    return Format::kUnknown;
}

struct Options {
    std::unique_ptr<tint::StyledTextPrinter> printer;

    std::string input_filename;
    std::string output_filename;

    Format format = Format::kUnknown;

    bool dump_wgsl = false;
    bool dump_spirv = false;
};

bool ParseArgs(tint::VectorRef<std::string_view> arguments, Options* opts) {
    using namespace tint::cli;  // NOLINT(build/namespaces)

    OptionSet options;

    tint::Vector<EnumName<Format>, 3> format_enum_names{
        EnumName(Format::kSpirv, "spirv"),
        EnumName(Format::kSpvAsm, "spvasm"),
        EnumName(Format::kWgsl, "wgsl"),
    };

    auto& fmt = options.Add<EnumOption<Format>>("format",
                                                R"(Output format to be written to file.
If not provided, will be inferred from output filename extension:
  .spvasm -> spvasm
  .spv    -> spirv
  .wgsl   -> wgsl)",
                                                format_enum_names, ShortName{"f"});
    TINT_DEFER(opts->format = fmt.value.value_or(Format::kUnknown));

    auto& col = options.Add<EnumOption<tint::ColorMode>>(
        "color", "Use colored output",
        tint::Vector{
            EnumName{tint::ColorMode::kPlain, "off"},
            EnumName{tint::ColorMode::kDark, "dark"},
            EnumName{tint::ColorMode::kLight, "light"},
        },
        ShortName{"col"}, Default{tint::ColorModeDefault()});
    TINT_DEFER(opts->printer = CreatePrinter(*col.value));

    auto& output = options.Add<StringOption>(
        "output-filename",
        "Output file name for shader output, if not specified nothing will be written to file",
        ShortName{"o"}, Parameter{"name"});
    TINT_DEFER(opts->output_filename = output.value.value_or(""));

    auto& dump_wgsl = options.Add<BoolOption>(
        "dump-wgsl", "Writes the WGSL form of input to stdout, may fail due to validation errors",
        Alias{"emit-wgsl"}, Default{false});
    TINT_DEFER(opts->dump_wgsl = *dump_wgsl.value);

    auto& dump_spirv = options.Add<BoolOption>(
        "dump-spirv",
        "Writes the SPIR-V form of input to stdout, may fail due to validation errors",
        Alias{"emit-spirv"}, Default{false});
    TINT_DEFER(opts->dump_spirv = *dump_spirv.value);

    auto& help = options.Add<BoolOption>("help", "Show usage", ShortName{"h"});

    auto show_usage = [&] {
        std::cout << R"(Usage: ir_fuzz_dis [options] <input-file>

Options:
)";
        options.ShowHelp(std::cout);
    };

    auto result = options.Parse(arguments);
    if (result != tint::Success) {
        std::cerr << result.Failure() << "\n";
        show_usage();
        return false;
    }

    if (help.value.value_or(false)) {
        show_usage();
        return false;
    }

    auto args = result.Get();
    if (args.Length() > 1) {
        std::cerr << "More than one input arg specified: "
                  << tint::Join(Transform(args, tint::Quote), ", ") << "\n";
        return false;
    }

    if (args.Length() == 1) {
        opts->input_filename = args[0];
    }

    return true;
}

/// Infer any missing option values, then validate that the provide values are
/// usable
/// @param options set of values provided by the user to the binary
/// @returns true if the options are usable, otherwise false. Prints error messages to STDERR
bool InferAndValidateOptions(Options& options) {
    if (options.format == Format::kUnknown && !options.output_filename.empty()) {
        options.format = InferFormat(options.output_filename);
        if (options.format == Format::kUnknown) {
            std::cerr << "Unable to determine output format from filename, "
                      << options.output_filename << "\n";
            return false;
        }
    }

    if (options.format != Format::kUnknown && options.output_filename.empty()) {
        std::cerr << "Format provided, but no output filename provided\n";
        return false;
    }

    return true;
}

/// @returns a fuzzer test case protobuf for the given file
/// @param options program options that contains the filename to be read, etc.
tint::Result<tint::cmd::fuzz::ir::pb::Root> GenerateFuzzCaseProto(const Options& options) {
    tint::cmd::fuzz::ir::pb::Root fuzz_pb;

    std::fstream input(options.input_filename, std::ios::in | std::ios::binary);
    if (!fuzz_pb.ParseFromIstream(&input)) {
        return tint::Failure{"Unable to parse bytes into test case protobuf"};
    }

    return std::move(fuzz_pb);
}

/// Prints IR text representation to STDOUT
/// @param options options passed into the binary
/// @param module IR module parsed from input protobuf
void EmitIR(const Options& options, tint::core::ir::Module& module) {
    const auto ir_text = tint::core::ir::Disassembler(module).Text();
    if (options.output_filename.empty()) {
        options.printer->Print(ir_text);
        options.printer->Print(tint::StyledText{} << "\n");
    }
}

/// Prints WGSL shader to STDOUT or to a file as determined by options
/// @param options options passed into the binary
/// @param module IR module parsed from input protobuf
/// @returns true if all operations succeeded, otherwise false. Prints error messages to STDERR
bool EmitWGSL(const Options& options, tint::core::ir::Module& module) {
    if (!options.dump_wgsl && options.format != Format::kWgsl) {
        return true;
    }

    tint::wgsl::writer::ProgramOptions writer_options;
    auto output = tint::wgsl::writer::WgslFromIR(module, writer_options);
    if (output != tint::Success) {
        std::cerr << "Failed to convert IR to WGSL Program: " << output.Failure() << "\n";
        return false;
    }

    if (options.dump_wgsl) {
        options.printer->Print(tint::StyledText{} << output->wgsl);
        options.printer->Print(tint::StyledText{} << "\n");
    }

    if (options.format == Format::kWgsl) {
        if (!tint::cmd::WriteFile(options.output_filename, "w", output->wgsl)) {
            std::cerr << "Unable to print WGSL to file, " << options.output_filename << "\n";
            return false;
        }
    }

    return true;
}

/// Prints SPIR-V shader to STDOUT or to a file as determined by options
/// @param options options passed into the binary
/// @param module IR module parsed from input protobuf
/// @returns true if all operations succeeded, otherwise false. Prints error messages to STDERR
bool EmitSpv(const Options& options, tint::core::ir::Module& module) {
    if (!options.dump_spirv && options.format != Format::kSpirv &&
        options.format != Format::kSpvAsm) {
        return true;
    }
    tint::spirv::writer::Options gen_options;
    auto spv = tint::spirv::writer::Generate(module, gen_options);

    if (spv != tint::Success) {
        std::cerr << "Failed to convert IR to SPIR-V: " << spv.Failure() << "\n";
        return false;
    }

    if (options.dump_spirv || options.format == Format::kSpvAsm) {
        auto spv_asm = DisassembleSpv(spv.Get().spirv);
        if (spv_asm != tint::Success) {
            std::cerr << "Failed to disassemble SPIR-V: " << spv_asm.Failure() << "\n";
            return false;
        }

        if (options.dump_spirv) {
            options.printer->Print(tint::StyledText{} << spv_asm.Get());
            options.printer->Print(tint::StyledText{} << "\n");
        }

        if (options.format == Format::kSpvAsm) {
            if (!tint::cmd::WriteFile(options.output_filename, "w", spv_asm.Get())) {
                std::cerr << "Unable to print SPIR-V text to file, " << options.output_filename
                          << "\n";
                return false;
            }
        }
    }

    if (options.format == Format::kSpirv) {
        if (!tint::cmd::WriteFile(options.output_filename, "wb", spv.Get().spirv)) {
            std::cerr << "Unable to print SPIR-V to file, " << options.output_filename << "\n";
            return false;
        }
    }
    return true;
}

/// Converts and displays the given test case file as determined by the options
///
/// NB: There is multiple ::Decode calls, because each emission step may modify the passed in Module
/// and modules are intentionally non-copyable.
///
/// @param options options passed into the binary
/// @returns true if all operations succeeded, otherwise false. Prints error messages to STDERR
bool Run(const Options& options) {
    auto fuzz_pb = GenerateFuzzCaseProto(options);
    if (fuzz_pb != tint::Success) {
        std::cerr << "Failed to read test case protobuf: " << fuzz_pb.Failure() << "\n";
        return false;
    }

    {
        auto module = tint::core::ir::binary::Decode(fuzz_pb.Get().module());
        if (module != tint::Success) {
            std::cerr << "Unable to decode ir protobuf from test case protobuf: "
                      << module.Failure() << "\n";
            return false;
        }
    }

    {
        auto module = tint::core::ir::binary::Decode(fuzz_pb.Get().module());
        EmitIR(options, module.Get());
    }

    {
        auto module = tint::core::ir::binary::Decode(fuzz_pb.Get().module());
        if (!EmitWGSL(options, module.Get())) {
            return false;
        }
    }

    {
        auto module = tint::core::ir::binary::Decode(fuzz_pb.Get().module());
        if (!EmitSpv(options, module.Get())) {
            return false;
        }
    }

    return true;
}

}  // namespace

int main(int argc, const char** argv) {
    tint::Vector<std::string_view, 8> arguments;
    for (int i = 1; i < argc; i++) {
        std::string_view arg(argv[i]);
        if (!arg.empty()) {
            arguments.Push(argv[i]);
        }
    }

    Options options;

    tint::Initialize();
    tint::SetInternalCompilerErrorReporter(&tint::cmd::TintInternalCompilerErrorReporter);

    if (!ParseArgs(arguments, &options)) {
        return EXIT_FAILURE;
    }

    if (!InferAndValidateOptions(options)) {
        return EXIT_FAILURE;
    }

    if (!Run(options)) {
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
