// Copyright (c) 2022 The Khronos Group Inc.
//
// 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.

#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif

#include "source/diff/diff.h"
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
#include "spirv-tools/libspirv.hpp"
#include "tools/io.h"
#include "tools/util/cli_consumer.h"
#include "tools/util/flags.h"

namespace {

constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;

constexpr bool kColorIsPossible =
#if SPIRV_COLOR_TERMINAL
    true;
#else
    false;
#endif

void print_usage(const char* argv0) {
  printf(R"(%s - Compare two SPIR-V files

Usage: %s <src_filename> <dst_filename>

The SPIR-V binary is read from <src_filename> and <dst_filename>.  If either
file ends in .spvasm, the SPIR-V is read as text and disassembled.

The contents of the SPIR-V modules are analyzed and a diff is produced showing a
logical transformation from src to dst, in src's id-space.

  -h, --help      Print this help.
  --version       Display diff version information.

  --color         Force color output. The default when printing to a terminal.
                  If both --color and --no-color is present, --no-color prevails.
  --no-color      Don't print in color. The default when output goes to
                  something other than a terminal (e.g. a pipe, or a shell
                  redirection).
                  If both --color and --no-color is present, --no-color prevails.

  --no-indent     Don't indent instructions.

  --no-header     Don't output the header as leading comments.

  --with-id-map   Also output the mapping between src and dst outputs.

  --ignore-set-binding
                  Don't use set/binding decorations for variable matching.
  --ignore-location
                  Don't use location decorations for variable matching.
)",
         argv0, argv0);
}

bool is_assembly(const char* path) {
  const char* suffix = strrchr(path, '.');
  if (suffix == nullptr) {
    return false;
  }

  return strcmp(suffix, ".spvasm") == 0;
}

std::unique_ptr<spvtools::opt::IRContext> load_module(const char* path) {
  if (is_assembly(path)) {
    std::vector<char> contents;
    if (!ReadTextFile(path, &contents)) return {};

    return spvtools::BuildModule(
        kDefaultEnvironment, spvtools::utils::CLIMessageConsumer,
        std::string(contents.begin(), contents.end()),
        static_cast<spv_text_to_binary_options_t>(
            spvtools::SpirvTools::kDefaultAssembleOption) |
            SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  }

  std::vector<uint32_t> contents;
  if (!ReadBinaryFile(path, &contents)) return {};

  return spvtools::BuildModule(kDefaultEnvironment,
                               spvtools::utils::CLIMessageConsumer,
                               contents.data(), contents.size());
}

}  // namespace

// clang-format off
FLAG_SHORT_bool(h,                  /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( help,               /* default_value= */ false, /* required= */false);
FLAG_LONG_bool( version,            /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( color,              /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( no_color,           /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( no_indent,          /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( no_header,          /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( with_id_map,        /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( ignore_set_binding, /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool( ignore_location,    /* default_value= */ false, /* required= */ false);
// clang-format on

int main(int, const char* argv[]) {
  if (!flags::Parse(argv)) {
    return 1;
  }

  if (flags::h.value() || flags::help.value()) {
    print_usage(argv[0]);
    return 0;
  }

  if (flags::version.value()) {
    printf("%s\n", spvSoftwareVersionDetailsString());
    printf("Target: %s\n", spvTargetEnvDescription(kDefaultEnvironment));
    return 0;
  }

  if (flags::positional_arguments.size() != 2) {
    fprintf(stderr, "error: two input files required.\n");
    return 1;
  }

#if defined(_POSIX_VERSION)
  const bool output_is_tty = isatty(fileno(stdout));
#else
  const bool output_is_tty = true;
#endif

  const std::string& src_file = flags::positional_arguments[0];
  const std::string& dst_file = flags::positional_arguments[1];

  spvtools::diff::Options options;
  options.color_output = (output_is_tty || flags::color.value()) &&
                         !flags::no_color.value() && kColorIsPossible;
  options.indent = !flags::no_indent.value();
  options.no_header = flags::no_header.value();
  options.dump_id_map = flags::with_id_map.value();
  options.ignore_set_binding = flags::ignore_set_binding.value();
  options.ignore_location = flags::ignore_location.value();

  std::unique_ptr<spvtools::opt::IRContext> src = load_module(src_file.c_str());
  std::unique_ptr<spvtools::opt::IRContext> dst = load_module(dst_file.c_str());

  if (!src) {
    fprintf(stderr, "error: Loading src file\n");
  }
  if (!dst) {
    fprintf(stderr, "error: Loading dst file\n");
  }
  if (!src || !dst) {
    return 1;
  }

  spvtools::diff::Diff(src.get(), dst.get(), std::cout, options);

  return 0;
}
