// Copyright 2017-2020 The Verible Authors.
//
// 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.

// verilog_diff compares the lexical contents of two Verilog source code
// texts.  Inputs only need to be lexically valid, not necessarily syntactically
// valid.  Use '-' to read from stdin.
// Differences are reported to stdout.
// The program exits 0 if no differences are found, else non-zero.
//
// Example usage:
// verilog_diff [options] file1 file2

#include <iostream>
#include <sstream>  // IWYU pragma: keep  // for ostringstream
#include <string>   // for string, allocator, etc

#include "absl/flags/flag.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "common/strings/obfuscator.h"
#include "common/util/enum_flags.h"
#include "common/util/file_util.h"
#include "common/util/init_command_line.h"
#include "common/util/logging.h"
#include "verilog/analysis/verilog_equivalence.h"

// Enumeration type for selecting
enum class DiffMode {
  // TODO(fangism): kNone: none of the existing presets, let the user compose
  // the filter predicate and comparator independently.
  kFormat,
  kObfuscate,
};

static const verible::EnumNameMap<DiffMode>& DiffModeStringMap() {
  static const verible::EnumNameMap<DiffMode> kDiffModeStringMap({
      {"format", DiffMode::kFormat},
      {"obfuscate", DiffMode::kObfuscate},
  });
  return kDiffModeStringMap;
}

std::ostream& operator<<(std::ostream& stream, DiffMode p) {
  return DiffModeStringMap().Unparse(p, stream);
}

bool AbslParseFlag(absl::string_view text, DiffMode* mode, std::string* error) {
  return DiffModeStringMap().Parse(text, mode, error, "--mode value");
}

std::string AbslUnparseFlag(const DiffMode& mode) {
  std::ostringstream stream;
  stream << mode;
  return stream.str();
}

ABSL_FLAG(DiffMode, mode, DiffMode::kFormat,
          R"(Defines difference functions.
  format: ignore whitespaces, compare token texts.
    This is useful for verifying formatter (e.g. verilog_format) output.
  obfuscate: preserve whitespaces, compare token texts' lengths only.
    This is useful for verifying verilog_obfuscate output.
)");

using EquivalenceFunctionType = std::function<verilog::DiffStatus(
    absl::string_view, absl::string_view, std::ostream*)>;

static const std::map<DiffMode, EquivalenceFunctionType> diff_func_map({
    {DiffMode::kFormat, verilog::FormatEquivalent},
    {DiffMode::kObfuscate, verilog::ObfuscationEquivalent},
});

int main(int argc, char** argv) {
  const auto usage = absl::StrCat("usage: ", argv[0],
                                  " [options] file1 file2\n"
                                  "Use - as a file name to read from stdin.");
  const auto args = verible::InitCommandLine(usage, &argc, &argv);

  enum {
    // inputs differ or there is some lexical error in one of the inputs
    kInputDifferenceErrorCode = 1,

    // error with flags or opening/reading one of the files
    kUserErrorCode = 2,
  };

  if (args.size() != 3) {
    std::cerr << "Program requires 2 positional arguments for input files."
              << std::endl;
    return kUserErrorCode;
  }

  // Open both files.
  std::string content1;
  absl::Status status = verible::file::GetContents(args[1], &content1);
  if (!status.ok()) {
    std::cerr << args[1] << ": " << status << std::endl;
    return kUserErrorCode;
  }
  std::string content2;
  status = verible::file::GetContents(args[2], &content2);
  if (!status.ok()) {
    std::cerr << args[1] << ": " << status << std::endl;
    return kUserErrorCode;
  }

  // Selection diff-ing function.
  const auto diff_mode = absl::GetFlag(FLAGS_mode);
  const auto iter = diff_func_map.find(diff_mode);
  CHECK(iter != diff_func_map.end());
  const auto diff_func = iter->second;

  // Compare.
  std::ostringstream errstream;
  const auto diff_status = diff_func(content1, content2, &errstream);

  // Signal result of comparison.
  switch (diff_status) {
    case verilog::DiffStatus::kEquivalent: {
      std::cout << "Inputs match." << std::endl;
      break;
    }
    case verilog::DiffStatus::kDifferent: {
      std::cout << "Inputs differ.\n" << errstream.str() << std::endl;
      return kInputDifferenceErrorCode;
    }
    case verilog::DiffStatus::kLeftError: {
      std::cout << "Lexical error in first file.\n"
                << errstream.str() << std::endl;
      return kInputDifferenceErrorCode;
    }
    case verilog::DiffStatus::kRightError: {
      std::cout << "Lexical error in second file.\n"
                << errstream.str() << std::endl;
      return kInputDifferenceErrorCode;
    }
  }
  return 0;
}
