// 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 <memory>
#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 {
  verilog::FileList file_list;
  // See --file_list_root above.
  std::string file_list_root;

  absl::Status LoadFromGlobalFlags() {
    file_list.preprocessing.include_dirs =
        absl::GetFlag(FLAGS_include_dir_paths);

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

    file_list_root = absl::GetFlag(FLAGS_file_list_root);

    return verilog::AppendFileListFromFile(file_list.file_list_path,
                                           &file_list);
  }
};

// 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 = std::make_unique<verilog::VerilogProject>(
        config.file_list_root, config.file_list.preprocessing.include_dirs);
    for (const auto& file : config.file_list.file_paths) {
      const auto open_status = project->OpenTranslationUnit(file);
      if (!open_status.ok()) return open_status.status();
    }

    // Initialize symbol table (empty).
    symbol_table = std::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.file_list.file_paths) {
      symbol_table->BuildSingleTranslationUnit(file, build_statuses);
    }
  }

  // Resolves symbols.
  void Resolve(std::vector<absl::Status>* resolve_statuses) const {
    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;
  if (auto status = config.LoadFromGlobalFlags(); !status.ok()) {
    return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  if (auto status = project_symbols.Load(); !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;
  if (auto status = config.LoadFromGlobalFlags(); !status.ok()) {
    return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  if (auto status = project_symbols.Load(); !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;
  if (auto status = config.LoadFromGlobalFlags(); !status.ok()) {
    return status;
  }

  // Load project and files.
  ProjectSymbols project_symbols(config);
  if (auto status = project_symbols.Load(); !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[]) {
  // 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;
}
