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

#include <functional>
#include <iostream>
#include <string>

#include "absl/flags/flag.h"
#include "absl/flags/usage.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "common/util/file_util.h"
#include "common/util/init_command_line.h"
#include "common/util/logging.h"
#include "common/util/subcommand.h"
#include "verilog/analysis/dependencies.h"
#include "verilog/analysis/symbol_table.h"
#include "verilog/analysis/verilog_project.h"

// Note: These flags were copied over from
// verilog/tools/kythe/verilog_kythe_extractor.cc.
// TODO: standardize Verilog project flags across tools.
ABSL_FLAG(
    std::string, file_list_path, "",
    R"(The path to the file list which contains the names of SystemVerilog files.
    The files should be ordered by definition dependencies.)");

ABSL_FLAG(
    std::string, file_list_root, ".",
    R"(The absolute location which we prepend to the files in the file list (where listed files are relative to).)");

// TODO: support repeatable flag
ABSL_FLAG(
    std::vector<std::string>, include_dir_paths, {},
    R"(Comma separated paths of the directories used to look for included files.
Note: The order of the files here is important.
File search will stop at the the first found among the listed directories.
e.g --include_dir_paths directory1,directory2
if "A.sv" exists in both "directory1" and "directory2" the one in "directory1" is the one we will use.
)");

using verible::SubcommandArgsRange;
using verible::SubcommandEntry;

// Project configuration information expected to come from command-line
// invocation.
// TODO: refactor for re-use in verilog/tools/kythe/verilog_kythe_extractor.cc
struct VerilogProjectConfig {
  // See --include_dir_paths above.
  std::vector<std::string> include_dir_paths;
  // See --file_list_path above.
  std::string file_list_path;
  // See --file_list_root above.
  std::string file_list_root;

  // Not a flag, but loaded from file_list_path.
  std::vector<std::string> files_names;

  absl::Status LoadFromGlobalFlags() {
    include_dir_paths = absl::GetFlag(FLAGS_include_dir_paths);

    file_list_path = absl::GetFlag(FLAGS_file_list_path);
    if (file_list_path.empty()) {
      return absl::InvalidArgumentError(
          "--file_list_path is required but missing.");
    }

    file_list_root = absl::GetFlag(FLAGS_file_list_root);

    // Load file list.
    const auto files_names_or_status(
        verilog::ParseSourceFileListFromFile(file_list_path));
    if (!files_names_or_status.ok()) return files_names_or_status.status();
    files_names = std::move(*files_names_or_status);

    return absl::OkStatus();
  }
};

// Holds VerilogProject and SymbolTable together with proper object lifetime.
// TODO: refactor this for re-use with tools/kythe/verilog_kythe_extractor.cc.
struct ProjectSymbols {
  // From global absl flags.
  const VerilogProjectConfig& config;

  // This object must outlive 'symbol_table' (maintained by struct-ordering).
  std::unique_ptr<verilog::VerilogProject> project;

  // Unified symbol table.
  std::unique_ptr<verilog::SymbolTable> symbol_table;

  explicit ProjectSymbols(const VerilogProjectConfig& config)
      : config(config) {}

  // no copy, no move, no assign
  ProjectSymbols(const ProjectSymbols&) = delete;
  ProjectSymbols(ProjectSymbols&&) = delete;
  ProjectSymbols& operator=(const ProjectSymbols&) = delete;
  ProjectSymbols& operator=(ProjectSymbols&&) = delete;

  // Initializes a project, and opens listed files.
  absl::Status Load() {
    VLOG(1) << __FUNCTION__;
    // Load all source files first.
    // Error-out early if any files failed to open.
    project = absl::make_unique<verilog::VerilogProject>(
        config.file_list_root, config.include_dir_paths);
    for (const auto& file : config.files_names) {
      const auto open_status = project->OpenTranslationUnit(file);
      if (!open_status.ok()) return open_status.status();
    }

    // Initialize symbol table (empty).
    symbol_table = absl::make_unique<verilog::SymbolTable>(project.get());
    return absl::OkStatus();
  }

  // Builds symbol table.
  void Build(std::vector<absl::Status>* build_statuses) {
    VLOG(1) << __FUNCTION__;
    // For now, ingest files in the order they were listed.
    // Without conflicting definitions in files, this order should not matter.
    for (const auto& file : config.files_names) {
      symbol_table->BuildSingleTranslationUnit(file, build_statuses);
    }
  }

  // Resolves symbols.
  void Resolve(std::vector<absl::Status>* resolve_statuses) {
    symbol_table->Resolve(resolve_statuses);
  }
};

static std::string JoinStatusMessages(
    const std::vector<absl::Status>& statuses) {
  return absl::StrCat(
      "[combined statuses]:\n",
      absl::StrJoin(
          statuses, "\n", [](std::string* out, const absl::Status& status) {
            out->append(status.message().begin(), status.message().end());
          }));
}

static absl::Status BuildAndShowSymbolTable(const SubcommandArgsRange& args,
                                            std::istream& ins,
                                            std::ostream& outs,
                                            std::ostream& errs) {
  VLOG(1) << __FUNCTION__;
  // Load configuration.
  VerilogProjectConfig config;
  {
    const auto status = config.LoadFromGlobalFlags();
    if (!status.ok()) return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  {
    const auto status = project_symbols.Load();
    if (!status.ok()) return status;
  }

  // Build symbol table.
  std::vector<absl::Status> build_statuses;
  project_symbols.Build(&build_statuses);

  // Print.
  outs << "Symbol Table:" << std::endl;
  project_symbols.symbol_table->PrintSymbolDefinitions(outs) << std::endl;

  // Accumulate diagnostics.
  if (!build_statuses.empty()) {
    return absl::InvalidArgumentError(JoinStatusMessages(build_statuses));
  }

  return absl::OkStatus();
}

static absl::Status ResolveAndShowSymbolReferences(
    const SubcommandArgsRange& args, std::istream& ins, std::ostream& outs,
    std::ostream& errs) {
  VLOG(1) << __FUNCTION__;
  // Load configuration.
  VerilogProjectConfig config;
  {
    const auto status = config.LoadFromGlobalFlags();
    if (!status.ok()) return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  {
    const auto status = project_symbols.Load();
    if (!status.ok()) return status;
  }

  // Build symbol table.
  std::vector<absl::Status> statuses;
  project_symbols.Build(&statuses);

  // Resolve symbols.
  project_symbols.Resolve(&statuses);

  // Print.
  outs << "Symbol References:" << std::endl;
  project_symbols.symbol_table->PrintSymbolReferences(outs) << std::endl;

  // Accumulate diagnostics.
  if (!statuses.empty()) {
    return absl::InvalidArgumentError(JoinStatusMessages(statuses));
  }

  return absl::OkStatus();
}

static absl::Status ShowFileDependencies(const SubcommandArgsRange& args,
                                         std::istream& ins, std::ostream& outs,
                                         std::ostream& errs) {
  VLOG(1) << __FUNCTION__;
  // Load configuration.
  VerilogProjectConfig config;
  {
    const auto status = config.LoadFromGlobalFlags();
    if (!status.ok()) return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  {
    const auto status = project_symbols.Load();
    if (!status.ok()) return status;
  }

  // Build symbol table.
  std::vector<absl::Status> statuses;
  project_symbols.Build(&statuses);

  // Accumulate diagnostics.
  if (!statuses.empty()) {
    return absl::InvalidArgumentError(JoinStatusMessages(statuses));
  }

  // Partially resolve symbols.
  project_symbols.symbol_table->ResolveLocallyOnly();

  // Compute dependencies.
  const verilog::FileDependencies deps(*project_symbols.symbol_table);

  // Print.
  // TODO(hzeller): support various output options {human-readable,
  // machine-readable, etc.} using subcommand flags (b/164300992).
  // One variant should include tsort-consumable 2-column text.
  deps.PrintGraph(outs);
  return absl::OkStatus();
}

static const std::pair<absl::string_view, SubcommandEntry> kCommands[] = {
    {"symbol-table-defs",        //
     {&BuildAndShowSymbolTable,  //
      R"(symbol-table-defs [project args]

Prints human-readable unified symbol table representation of all files.
This does not attempt to resolve symbols.

Input:
Project options, including source file list.
)"}},
    {"symbol-table-refs",               //
     {&ResolveAndShowSymbolReferences,  //
      R"(symbol-table-refs [project args]

Prints human-readable representation of symbol table references, after
attempting to resolve symbols.

Input:
Project options, including source file list.
)"}},
    {"file-deps",             //
     {&ShowFileDependencies,  //
      R"(file-deps [project args]

Prints human-readable representation of inter-file dependencies, e.g.

  "file1.sv" depends on "file2.sv" for symbols { X, Y, Z... }

Input:
Project options, including source file list.
)"}},
    // TODO: project-wide transformations like RenameSymbol()
    // TODO: symbol table name-completion demo
};

int main(int argc, char* argv[]) {
  VLOG(1) << __FUNCTION__;
  // Create a registry of subcommands (locally, rather than as a static global).
  verible::SubcommandRegistry commands;
  for (const auto& entry : kCommands) {
    const auto status = commands.RegisterCommand(entry.first, entry.second);
    if (!status.ok()) {
      std::cerr << status.message() << std::endl;
      return 2;  // fatal error
    }
  }

  const std::string usage = absl::StrCat("usage: ", argv[0],
                                         " command args...\n"
                                         "available commands:\n",
                                         commands.ListCommands());

  // Process invocation args.
  const auto args = verible::InitCommandLine(usage, &argc, &argv);
  if (args.size() == 1) {
    std::cerr << absl::ProgramUsageMessage() << std::endl;
    return 1;
  }
  // args[0] is the program name
  // args[1] is the subcommand
  // subcommand args start at [2]
  const SubcommandArgsRange command_args(args.cbegin() + 2, args.cend());

  const auto& sub = commands.GetSubcommandEntry(args[1]);
  // Run the subcommand.
  const auto status = sub.main(command_args, std::cin, std::cout, std::cerr);
  if (!status.ok()) {
    std::cerr << status.message() << std::endl;
    return 1;
  }
  return 0;
}
