// Copyright (c) 2015-2016 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 <stdio.h>  // Need fileno
#include <unistd.h>
#endif

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>

#include "spirv-tools/libspirv.h"
#include "tools/io.h"
#include "tools/util/flags.h"

static const std::string kHelpText = R"(%s - Disassemble a SPIR-V binary module

Usage: %s [options] [<filename>]

The SPIR-V binary is read from <filename>. If no file is specified,
or if the filename is "-", then the binary is read from standard input.

A text-based hex stream is also accepted as binary input, which should either
consist of 32-bit words or 8-bit bytes.  The 0x or x prefix is optional, but
should be consistently present in the stream.

Options:

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

  -o <filename>     Set the output filename.
                    Output goes to standard output if this option is
                    not specified, or if the filename is "-".

  --color           Force color output.  The default when printing to a terminal.
                    Overrides a previous --no-color option.
  --no-color        Don't print in color.  Overrides a previous --color option.
                    The default when output goes to something other than a
                    terminal (e.g. a file, a pipe, or a shell redirection).

  --no-indent       Don't indent instructions.

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

  --raw-id          Show raw Id values instead of friendly names.

  --nested-indent   Indentation is adjusted to indicate nesting in structured
                    control flow.

  --reorder-blocks  Reorder blocks to match the structured control flow of SPIR-V.
                    With this option, the order of instructions will no longer
                    match the input binary, but the result will be more readable.

  --offsets         Show byte offsets for each instruction.

  --comment         Add comments to make reading easier
)";

// clang-format off
FLAG_SHORT_bool  (h,              /* default_value= */ false, /* required= */ false);
FLAG_SHORT_string(o,              /* default_value= */ "-",   /* 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   (raw_id,         /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool   (nested_indent,  /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool   (reorder_blocks, /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool   (offsets,        /* default_value= */ false, /* required= */ false);
FLAG_LONG_bool   (comment,        /* default_value= */ false, /* required= */ false);
// clang-format on

static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;

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

  if (flags::h.value() || flags::help.value()) {
    printf(kHelpText.c_str(), argv[0], 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() > 1) {
    fprintf(stderr, "error: more than one input file specified.\n");
    return 1;
  }

  const std::string inFile = flags::positional_arguments.size() == 0
                                 ? "-"
                                 : flags::positional_arguments[0];
  const std::string outFile = flags::o.value();

  bool color_is_possible =
#if SPIRV_COLOR_TERMINAL
      true;
#else
      false;
#endif

  uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NONE;

  if (!flags::no_indent.value()) options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;

  if (flags::offsets.value())
    options |= SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET;

  if (flags::no_header.value()) options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER;

  if (!flags::raw_id.value())
    options |= SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;

  if (flags::nested_indent.value())
    options |= SPV_BINARY_TO_TEXT_OPTION_NESTED_INDENT;

  if (flags::reorder_blocks.value())
    options |= SPV_BINARY_TO_TEXT_OPTION_REORDER_BLOCKS;

  if (flags::comment.value()) options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT;

  if (flags::o.value() == "-") {
    // Print to standard output.
    options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;
    if (color_is_possible && !flags::no_color.value()) {
      bool output_is_tty = true;
#if defined(_POSIX_VERSION)
      output_is_tty = isatty(fileno(stdout));
#endif
      if (output_is_tty || flags::color.value()) {
        options |= SPV_BINARY_TO_TEXT_OPTION_COLOR;
      }
    }
  }

  // Read the input binary.
  std::vector<uint32_t> contents;
  if (!ReadBinaryFile(inFile.c_str(), &contents)) return 1;

  // If printing to standard output, then spvBinaryToText should
  // do the printing.  In particular, colour printing on Windows is
  // controlled by modifying console objects synchronously while
  // outputting to the stream rather than by injecting escape codes
  // into the output stream.
  // If the printing option is off, then save the text in memory, so
  // it can be emitted later in this function.
  const bool print_to_stdout = SPV_BINARY_TO_TEXT_OPTION_PRINT & options;
  spv_text text = nullptr;
  spv_text* textOrNull = print_to_stdout ? nullptr : &text;
  spv_diagnostic diagnostic = nullptr;
  spv_context context = spvContextCreate(kDefaultEnvironment);
  spv_result_t error =
      spvBinaryToText(context, contents.data(), contents.size(), options,
                      textOrNull, &diagnostic);
  spvContextDestroy(context);
  if (error) {
    spvDiagnosticPrint(diagnostic);
    spvDiagnosticDestroy(diagnostic);
    return error;
  }

  if (!print_to_stdout) {
    if (!WriteFile<char>(outFile.c_str(), "w", text->str, text->length)) {
      spvTextDestroy(text);
      return 1;
    }
  }
  spvTextDestroy(text);

  return 0;
}
