// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <cstring>
#include <fstream>
#include <memory>
#include <sstream>
#include <vector>

#include "test/cctest/interpreter/bytecode-expectations-printer.h"

#include "include/libplatform/libplatform.h"
#include "include/v8.h"

#include "src/base/logging.h"
#include "src/interpreter/interpreter.h"

#ifdef V8_OS_POSIX
#include <dirent.h>
#endif

using v8::internal::interpreter::BytecodeExpectationsPrinter;

#define REPORT_ERROR(MESSAGE) (((std::cerr << "ERROR: ") << MESSAGE) << '\n')

namespace {

const char* kGoldenFilesPath = "test/cctest/interpreter/bytecode_expectations/";

class ProgramOptions final {
 public:
  static ProgramOptions FromCommandLine(int argc, char** argv);

  ProgramOptions()
      : parsing_failed_(false),
        print_help_(false),
        read_raw_js_snippet_(false),
        read_from_stdin_(false),
        rebaseline_(false),
        check_baseline_(false),
        wrap_(true),
        module_(false),
        top_level_(false),
        print_callee_(false),
        oneshot_opt_(false),
        async_iteration_(false),
        private_methods_(false),
        verbose_(false) {}

  bool Validate() const;
  void UpdateFromHeader(std::istream& stream);   // NOLINT
  void PrintHeader(std::ostream& stream) const;  // NOLINT

  bool parsing_failed() const { return parsing_failed_; }
  bool print_help() const { return print_help_; }
  bool read_raw_js_snippet() const { return read_raw_js_snippet_; }
  bool read_from_stdin() const { return read_from_stdin_; }
  bool write_to_stdout() const {
    return output_filename_.empty() && !rebaseline_;
  }
  bool rebaseline() const { return rebaseline_; }
  bool check_baseline() const { return check_baseline_; }
  bool baseline() const { return rebaseline_ || check_baseline_; }
  bool wrap() const { return wrap_; }
  bool module() const { return module_; }
  bool top_level() const { return top_level_; }
  bool print_callee() const { return print_callee_; }
  bool oneshot_opt() const { return oneshot_opt_; }
  bool async_iteration() const { return async_iteration_; }
  bool private_methods() const { return private_methods_; }
  bool verbose() const { return verbose_; }
  bool suppress_runtime_errors() const { return baseline() && !verbose_; }
  std::vector<std::string> input_filenames() const { return input_filenames_; }
  std::string output_filename() const { return output_filename_; }
  std::string test_function_name() const { return test_function_name_; }

 private:
  bool parsing_failed_;
  bool print_help_;
  bool read_raw_js_snippet_;
  bool read_from_stdin_;
  bool rebaseline_;
  bool check_baseline_;
  bool wrap_;
  bool module_;
  bool top_level_;
  bool print_callee_;
  bool oneshot_opt_;
  bool async_iteration_;
  bool private_methods_;
  bool verbose_;
  std::vector<std::string> input_filenames_;
  std::string output_filename_;
  std::string test_function_name_;
};

class V8InitializationScope final {
 public:
  explicit V8InitializationScope(const char* exec_path);
  ~V8InitializationScope();

  v8::Platform* platform() const { return platform_.get(); }
  v8::Isolate* isolate() const { return isolate_; }

 private:
  std::unique_ptr<v8::Platform> platform_;
  std::unique_ptr<v8::ArrayBuffer::Allocator> allocator_;
  v8::Isolate* isolate_;

  DISALLOW_COPY_AND_ASSIGN(V8InitializationScope);
};

bool ParseBoolean(const char* string) {
  if (strcmp(string, "yes") == 0) {
    return true;
  } else if (strcmp(string, "no") == 0) {
    return false;
  } else {
    UNREACHABLE();
  }
}

const char* BooleanToString(bool value) { return value ? "yes" : "no"; }

bool CollectGoldenFiles(std::vector<std::string>* golden_file_list,
                        const char* directory_path) {
#ifdef V8_OS_POSIX
  DIR* directory = opendir(directory_path);
  if (!directory) return false;

  auto str_ends_with = [](const char* string, const char* suffix) {
    size_t string_size = strlen(string);
    size_t suffix_size = strlen(suffix);
    if (string_size < suffix_size) return false;

    return strcmp(string + (string_size - suffix_size), suffix) == 0;
  };

  dirent* entry = readdir(directory);
  while (entry) {
    if (str_ends_with(entry->d_name, ".golden")) {
      std::string golden_filename(kGoldenFilesPath);
      golden_filename += entry->d_name;
      golden_file_list->push_back(golden_filename);
    }
    entry = readdir(directory);
  }

  closedir(directory);
#elif V8_OS_WIN
  std::string search_path(directory_path + std::string("/*.golden"));
  WIN32_FIND_DATAA fd;
  HANDLE find_handle = FindFirstFileA(search_path.c_str(), &fd);
  if (find_handle == INVALID_HANDLE_VALUE) return false;
  do {
    if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      std::string golden_filename(kGoldenFilesPath);
      std::string temp_filename(fd.cFileName);
      golden_filename += temp_filename;
      golden_file_list->push_back(golden_filename);
    }
  } while (FindNextFileA(find_handle, &fd));
  FindClose(find_handle);
#endif  // V8_OS_POSIX
  return true;
}

// static
ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) {
  ProgramOptions options;

  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i], "--help") == 0) {
      options.print_help_ = true;
    } else if (strcmp(argv[i], "--raw-js") == 0) {
      options.read_raw_js_snippet_ = true;
    } else if (strcmp(argv[i], "--stdin") == 0) {
      options.read_from_stdin_ = true;
    } else if (strcmp(argv[i], "--rebaseline") == 0) {
      options.rebaseline_ = true;
    } else if (strcmp(argv[i], "--check-baseline") == 0) {
      options.check_baseline_ = true;
    } else if (strcmp(argv[i], "--no-wrap") == 0) {
      options.wrap_ = false;
    } else if (strcmp(argv[i], "--module") == 0) {
      options.module_ = true;
    } else if (strcmp(argv[i], "--top-level") == 0) {
      options.top_level_ = true;
    } else if (strcmp(argv[i], "--print-callee") == 0) {
      options.print_callee_ = true;
    } else if (strcmp(argv[i], "--disable-oneshot-opt") == 0) {
      options.oneshot_opt_ = false;
    } else if (strcmp(argv[i], "--async-iteration") == 0) {
      options.async_iteration_ = true;
    } else if (strcmp(argv[i], "--private-methods") == 0) {
      options.private_methods_ = true;
    } else if (strcmp(argv[i], "--verbose") == 0) {
      options.verbose_ = true;
    } else if (strncmp(argv[i], "--output=", 9) == 0) {
      options.output_filename_ = argv[i] + 9;
    } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) {
      options.test_function_name_ = argv[i] + 21;
    } else if (strncmp(argv[i], "--", 2) != 0) {  // It doesn't start with --
      options.input_filenames_.push_back(argv[i]);
    } else {
      REPORT_ERROR("Unknown option " << argv[i]);
      options.parsing_failed_ = true;
      break;
    }
  }

  if (options.rebaseline() && options.check_baseline()) {
    REPORT_ERROR("Can't check baseline and rebaseline at the same time.");
    std::exit(1);
  }

  if ((options.check_baseline_ || options.rebaseline_) &&
      options.input_filenames_.empty()) {
#if defined(V8_OS_POSIX) || defined(V8_OS_WIN)
    if (options.verbose_) {
      std::cout << "Looking for golden files in " << kGoldenFilesPath << '\n';
    }
    if (!CollectGoldenFiles(&options.input_filenames_, kGoldenFilesPath)) {
      REPORT_ERROR("Golden files autodiscovery failed.");
      options.parsing_failed_ = true;
    }
#else
    REPORT_ERROR(
        "Golden files autodiscovery requires a POSIX or Window OS, sorry.");
    options.parsing_failed_ = true;
#endif
  }

  return options;
}

bool ProgramOptions::Validate() const {
  if (parsing_failed_) return false;
  if (print_help_) return true;

  if (!read_from_stdin_ && input_filenames_.empty()) {
    REPORT_ERROR("No input file specified.");
    return false;
  }

  if (read_from_stdin_ && !input_filenames_.empty()) {
    REPORT_ERROR("Reading from stdin, but input files supplied.");
    return false;
  }

  if (baseline() && read_raw_js_snippet_) {
    REPORT_ERROR(
        "Cannot use --rebaseline or --check-baseline on a raw JS snippet.");
    return false;
  }

  if (baseline() && !output_filename_.empty()) {
    REPORT_ERROR(
        "Output file cannot be specified together with --rebaseline or "
        "--check-baseline.");
    return false;
  }

  if (baseline() && read_from_stdin_) {
    REPORT_ERROR(
        "Cannot --rebaseline or --check-baseline when input is --stdin.");
    return false;
  }

  if (input_filenames_.size() > 1 && !baseline() && !read_raw_js_snippet()) {
    REPORT_ERROR(
        "Multiple input files, but no --rebaseline, --check-baseline or "
        "--raw-js specified.");
    return false;
  }

  if (top_level_ && !test_function_name_.empty()) {
    REPORT_ERROR(
        "Test function name specified while processing top level code.");
    return false;
  }

  if (module_ && (!top_level_ || wrap_)) {
    REPORT_ERROR(
        "The flag --module currently requires --top-level and --no-wrap.");
    return false;
  }

  return true;
}

void ProgramOptions::UpdateFromHeader(std::istream& stream) {
  std::string line;
  const char* kPrintCallee = "print callee: ";
  const char* kOneshotOpt = "oneshot opt: ";

  // Skip to the beginning of the options header
  while (std::getline(stream, line)) {
    if (line == "---") break;
  }

  while (std::getline(stream, line)) {
    if (line.compare(0, 8, "module: ") == 0) {
      module_ = ParseBoolean(line.c_str() + 8);
    } else if (line.compare(0, 6, "wrap: ") == 0) {
      wrap_ = ParseBoolean(line.c_str() + 6);
    } else if (line.compare(0, 20, "test function name: ") == 0) {
      test_function_name_ = line.c_str() + 20;
    } else if (line.compare(0, 11, "top level: ") == 0) {
      top_level_ = ParseBoolean(line.c_str() + 11);
    } else if (line.compare(0, strlen(kPrintCallee), kPrintCallee) == 0) {
      print_callee_ = ParseBoolean(line.c_str() + strlen(kPrintCallee));
    } else if (line.compare(0, strlen(kOneshotOpt), kOneshotOpt) == 0) {
      oneshot_opt_ = ParseBoolean(line.c_str() + strlen(kOneshotOpt));
    } else if (line.compare(0, 17, "async iteration: ") == 0) {
      async_iteration_ = ParseBoolean(line.c_str() + 17);
    } else if (line.compare(0, 17, "private methods: ") == 0) {
      private_methods_ = ParseBoolean(line.c_str() + 17);
    } else if (line == "---") {
      break;
    } else if (line.empty()) {
      continue;
    } else {
      UNREACHABLE();
    }
  }
}

void ProgramOptions::PrintHeader(std::ostream& stream) const {  // NOLINT
  stream << "---"
         << "\nwrap: " << BooleanToString(wrap_);

  if (!test_function_name_.empty()) {
    stream << "\ntest function name: " << test_function_name_;
  }

  if (module_) stream << "\nmodule: yes";
  if (top_level_) stream << "\ntop level: yes";
  if (print_callee_) stream << "\nprint callee: yes";
  if (oneshot_opt_) stream << "\noneshot opt: yes";
  if (async_iteration_) stream << "\nasync iteration: yes";
  if (private_methods_) stream << "\nprivate methods: yes";

  stream << "\n\n";
}

V8InitializationScope::V8InitializationScope(const char* exec_path)
    : platform_(v8::platform::NewDefaultPlatform()) {
  i::FLAG_always_opt = false;
  i::FLAG_allow_natives_syntax = true;
  i::FLAG_enable_lazy_source_positions = false;

  v8::V8::InitializeICUDefaultLocation(exec_path);
  v8::V8::InitializeExternalStartupData(exec_path);
  v8::V8::InitializePlatform(platform_.get());
  v8::V8::Initialize();

  v8::Isolate::CreateParams create_params;
  allocator_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
  create_params.array_buffer_allocator = allocator_.get();

  isolate_ = v8::Isolate::New(create_params);
}

V8InitializationScope::~V8InitializationScope() {
  isolate_->Dispose();
  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();
}

std::string ReadRawJSSnippet(std::istream& stream) {  // NOLINT
  std::stringstream body_buffer;
  CHECK(body_buffer << stream.rdbuf());
  return body_buffer.str();
}

bool ReadNextSnippet(std::istream& stream, std::string* string_out) {  // NOLINT
  std::string line;
  bool found_begin_snippet = false;
  string_out->clear();
  while (std::getline(stream, line)) {
    if (line == "snippet: \"") {
      found_begin_snippet = true;
      continue;
    }
    if (!found_begin_snippet) continue;
    if (line == "\"") return true;
    if (line.size() == 0) {
      string_out->append("\n");  // consume empty line
      continue;
    }
    CHECK_GE(line.size(), 2u);  // We should have the indent
    string_out->append(line.begin() + 2, line.end());
    *string_out += '\n';
  }
  return false;
}

std::string UnescapeString(const std::string& escaped_string) {
  std::string unescaped_string;
  bool previous_was_backslash = false;
  for (char c : escaped_string) {
    if (previous_was_backslash) {
      // If it was not an escape sequence, emit the previous backslash
      if (c != '\\' && c != '"') unescaped_string += '\\';
      unescaped_string += c;
      previous_was_backslash = false;
    } else {
      if (c == '\\') {
        previous_was_backslash = true;
        // Defer emission to the point where we can check if it was an escape.
      } else {
        unescaped_string += c;
      }
    }
  }
  return unescaped_string;
}

void ExtractSnippets(std::vector<std::string>* snippet_list,
                     std::istream& body_stream,  // NOLINT
                     bool read_raw_js_snippet) {
  if (read_raw_js_snippet) {
    snippet_list->push_back(ReadRawJSSnippet(body_stream));
  } else {
    std::string snippet;
    while (ReadNextSnippet(body_stream, &snippet)) {
      snippet_list->push_back(UnescapeString(snippet));
    }
  }
}

void GenerateExpectationsFile(std::ostream& stream,  // NOLINT
                              const std::vector<std::string>& snippet_list,
                              const V8InitializationScope& platform,
                              const ProgramOptions& options) {
  v8::Isolate::Scope isolate_scope(platform.isolate());
  v8::HandleScope handle_scope(platform.isolate());
  v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
  v8::Context::Scope context_scope(context);

  BytecodeExpectationsPrinter printer(platform.isolate());
  printer.set_wrap(options.wrap());
  printer.set_module(options.module());
  printer.set_top_level(options.top_level());
  printer.set_print_callee(options.print_callee());
  printer.set_oneshot_opt(options.oneshot_opt());
  if (!options.test_function_name().empty()) {
    printer.set_test_function_name(options.test_function_name());
  }

  if (options.private_methods()) i::FLAG_harmony_private_methods = true;

  stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n";
  options.PrintHeader(stream);
  for (const std::string& snippet : snippet_list) {
    printer.PrintExpectation(stream, snippet);
  }

  i::FLAG_harmony_private_methods = false;
}

bool WriteExpectationsFile(const std::vector<std::string>& snippet_list,
                           const V8InitializationScope& platform,
                           const ProgramOptions& options,
                           const std::string& output_filename) {
  std::ofstream output_file_handle;
  if (!options.write_to_stdout()) {
    output_file_handle.open(output_filename.c_str());
    if (!output_file_handle.is_open()) {
      REPORT_ERROR("Could not open " << output_filename << " for writing.");
      return false;
    }
  }
  std::ostream& output_stream =
      options.write_to_stdout() ? std::cout : output_file_handle;

  GenerateExpectationsFile(output_stream, snippet_list, platform, options);

  return true;
}

std::string WriteExpectationsToString(
    const std::vector<std::string>& snippet_list,
    const V8InitializationScope& platform, const ProgramOptions& options) {
  std::stringstream output_string;

  GenerateExpectationsFile(output_string, snippet_list, platform, options);

  return output_string.str();
}

void PrintMessage(v8::Local<v8::Message> message, v8::Local<v8::Value>) {
  std::cerr << "INFO: "
            << *v8::String::Utf8Value(message->GetIsolate(), message->Get())
            << '\n';
}

void DiscardMessage(v8::Local<v8::Message>, v8::Local<v8::Value>) {}

void PrintUsage(const char* exec_path) {
  std::cerr
      << "\nUsage: " << exec_path
      << " [OPTIONS]... [INPUT FILES]...\n\n"
         "Options:\n"
         "  --help        Print this help message.\n"
         "  --verbose     Emit messages about the progress of the tool.\n"
         "  --raw-js      Read raw JavaScript, instead of the output format.\n"
         "  --stdin       Read from standard input instead of file.\n"
         "  --rebaseline  Rebaseline input snippet file.\n"
         "  --check-baseline   Checks the current baseline is valid.\n"
         "  --no-wrap     Do not wrap the snippet in a function.\n"
         "  --disable-oneshot-opt     Disable Oneshot Optimization.\n"
         "  --print-callee     Print bytecode of callee, function should "
         "return arguments.callee.\n"
         "  --module      Compile as JavaScript module.\n"
         "  --test-function-name=foo  "
         "Specify the name of the test function.\n"
         "  --top-level   Process top level code, not the top-level function.\n"
         "  --private-methods  Enable harmony_private_methods flag.\n"
         "  --output=file.name\n"
         "      Specify the output file. If not specified, output goes to "
         "stdout.\n"
         "  --pool-type=(number|string|mixed)\n"
         "      Specify the type of the entries in the constant pool "
         "(default: mixed).\n"
         "\n"
         "When using --rebaseline or --check-baseline, flags --no-wrap,\n"
         "--test-function-name and --pool-type will be overridden by the\n"
         "options specified in the input file header.\n\n"
         "Each raw JavaScript file is interpreted as a single snippet.\n\n"
         "This tool is intended as a help in writing tests.\n"
         "Please, DO NOT blindly copy and paste the output "
         "into the test suite.\n";
}

}  // namespace

bool CheckBaselineExpectations(const std::string& input_filename,
                               const std::vector<std::string>& snippet_list,
                               const V8InitializationScope& platform,
                               const ProgramOptions& options) {
  std::string actual =
      WriteExpectationsToString(snippet_list, platform, options);

  std::ifstream input_stream(input_filename);
  if (!input_stream.is_open()) {
    REPORT_ERROR("Could not open " << input_filename << " for reading.");
    std::exit(2);
  }

  bool check_failed = false;
  std::string expected((std::istreambuf_iterator<char>(input_stream)),
                       std::istreambuf_iterator<char>());
  if (expected != actual) {
    REPORT_ERROR("Mismatch: " << input_filename);
    check_failed = true;
    if (expected.size() != actual.size()) {
      REPORT_ERROR("  Expected size (" << expected.size()
                                       << ") != actual size (" << actual.size()
                                       << ")");
    }

    int line = 1;
    for (size_t i = 0; i < std::min(expected.size(), actual.size()); ++i) {
      if (expected[i] != actual[i]) {
        // Find the start of the line that has the mismatch carefully
        // handling the case where it's the first line that mismatches.
        size_t start = expected[i] != '\n' ? expected.rfind("\n", i)
                                           : actual.rfind("\n", i);
        if (start == std::string::npos) {
          start = 0;
        } else {
          ++start;
        }

        // If there is no new line, then these two lines will consume the
        // remaining characters in the string, because npos - start will
        // always be longer than the string itself.
        std::string expected_line =
            expected.substr(start, expected.find("\n", i) - start);
        std::string actual_line =
            actual.substr(start, actual.find("\n", i) - start);
        REPORT_ERROR("  First mismatch on line " << line << ")");
        REPORT_ERROR("    Expected : '" << expected_line << "'");
        REPORT_ERROR("    Actual   : '" << actual_line << "'");
        break;
      }
      if (expected[i] == '\n') line++;
    }
  }
  return check_failed;
}

int main(int argc, char** argv) {
  ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv);

  if (!options.Validate() || options.print_help()) {
    PrintUsage(argv[0]);
    return options.print_help() ? 0 : 1;
  }

  V8InitializationScope platform(argv[0]);
  platform.isolate()->AddMessageListener(
      options.suppress_runtime_errors() ? DiscardMessage : PrintMessage);

  std::vector<std::string> snippet_list;

  if (options.read_from_stdin()) {
    // Rebaseline will never get here, so we will always take the
    // GenerateExpectationsFile at the end of this function.
    DCHECK(!options.rebaseline() && !options.check_baseline());
    ExtractSnippets(&snippet_list, std::cin, options.read_raw_js_snippet());
  } else {
    bool check_failed = false;
    for (const std::string& input_filename : options.input_filenames()) {
      if (options.verbose()) {
        std::cerr << "Processing " << input_filename << '\n';
      }

      std::ifstream input_stream(input_filename.c_str());
      if (!input_stream.is_open()) {
        REPORT_ERROR("Could not open " << input_filename << " for reading.");
        return 2;
      }

      ProgramOptions updated_options = options;
      if (options.baseline()) {
        updated_options.UpdateFromHeader(input_stream);
        CHECK(updated_options.Validate());
      }

      ExtractSnippets(&snippet_list, input_stream,
                      options.read_raw_js_snippet());
      input_stream.close();

      if (options.rebaseline()) {
        if (!WriteExpectationsFile(snippet_list, platform, updated_options,
                                   input_filename)) {
          return 3;
        }
      } else if (options.check_baseline()) {
        check_failed |= CheckBaselineExpectations(input_filename, snippet_list,
                                                  platform, updated_options);
      }

      if (options.baseline()) {
        snippet_list.clear();
      }
    }
    if (check_failed) {
      return 4;
    }
  }

  if (!options.baseline()) {
    if (!WriteExpectationsFile(snippet_list, platform, options,
                               options.output_filename())) {
      return 3;
    }
  }
}
