// Copyright 2017-2023 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 "verilog/tools/ls/symbol-table-handler.h"

#include <filesystem>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "common/lsp/lsp-file-utils.h"
#include "common/lsp/lsp-protocol.h"
#include "common/lsp/lsp-text-buffer.h"
#include "common/util/file_util.h"
#include "gtest/gtest.h"
#include "verilog/analysis/verilog_project.h"
#include "verilog/tools/ls/lsp-parse-buffer.h"

namespace verilog {
namespace {

static constexpr absl::string_view  //
    kSampleModuleA(
        R"(module a;
  assign var1 = 1'b0;
  assign var2 = var1 | 1'b1;
endmodule
)");

static constexpr absl::string_view  //
    kSampleModuleB(
        R"(module b;
  assign var1 = 1'b0;
  assign var2 = var1 | 1'b1;
  a vara;
  assign vara.var1 = 1'b1;
endmodule
)");

// Tests the behavior of SymbolTableHandler for not existing directory.
TEST(SymbolTableHandlerTest, InitializationNoRoot) {
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      "non-existing-root", std::vector<std::string>());

  SymbolTableHandler symbol_table_handler;

  symbol_table_handler.SetProject(project);
}

// Tests the behavior of SymbolTableHandler for an empty directory.
TEST(SymbolTableHandlerTest, EmptyDirectoryProject) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>());

  SymbolTableHandler symbol_table_handler;

  symbol_table_handler.SetProject(project);

  symbol_table_handler.BuildProjectSymbolTable();
}

TEST(SymbolTableHandlerTest, NullVerilogProject) {
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(nullptr);
}

TEST(SymbolTableHandlerTest, InvalidFileListSyntax) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  const verible::file::testing::ScopedTestFile filelist(sources_dir, "@@",
                                                        "verible.filelist");

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>());

  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  symbol_table_handler.BuildProjectSymbolTable();
}

TEST(SymbolTableHandlerTest, LoadFileList) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>{});

  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  std::vector<absl::Status> diagnostics =
      symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_EQ(diagnostics.size(), 0);
}

TEST(SymbolTableHandlerTest, FileListWithNonExistingFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>{});

  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  std::vector<absl::Status> diagnostics =
      symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_EQ(diagnostics.size(), 1);
}

TEST(SymbolTableHandlerTest, MissingFileList) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>{});

  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  std::vector<absl::Status> diagnostics =
      symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_EQ(diagnostics.size(), 0);
}

TEST(SymbolTableHandlerTest, DefinitionNotTrackedFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");

  std::shared_ptr<VerilogProject> project =
      std::make_shared<VerilogProject>(sources_dir, std::vector<std::string>{});

  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verible::lsp::DefinitionParams gotorequest;
  gotorequest.textDocument.uri = "file://b.sv";
  gotorequest.position.line = 2;
  gotorequest.position.character = 17;

  std::vector<absl::Status> diagnostics =
      symbol_table_handler.BuildProjectSymbolTable();

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.FindBufferTrackerOrNull(gotorequest.textDocument.uri);
  EXPECT_EQ(
      parsed_buffers.FindBufferTrackerOrNull(gotorequest.textDocument.uri),
      nullptr);

  std::vector<verible::lsp::Location> location =
      symbol_table_handler.FindDefinitionLocation(gotorequest, parsed_buffers);
  EXPECT_EQ(location.size(), 0);
}

TEST(SymbolTableHandlerTest,
     FindRenamableRangeAtCursorReturnsNullUntrackedFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content = "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");
  verible::lsp::PrepareRenameParams parameters;
  parameters.textDocument.uri =
      verible::lsp::PathToLSPUri(sources_dir + "/c.sv");
  parameters.position.line = 1;
  parameters.position.character = 11;

  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // Add trackers for the files we're going to process - normally done by the
  // LSP but we don't have one
  auto a_buffer = verible::lsp::EditTextBuffer(kSampleModuleA);
  parsed_buffers.GetSubscriptionCallback()(
      verible::lsp::PathToLSPUri(sources_dir + "/a.sv"), &a_buffer);
  symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_FALSE(parsed_buffers.FindBufferTrackerOrNull(
                   parameters.textDocument.uri) != nullptr);

  std::optional<verible::lsp::Range> edit_range =
      symbol_table_handler.FindRenameableRangeAtCursor(parameters,
                                                       parsed_buffers);
  ASSERT_FALSE(edit_range.has_value());
}

// TODO(hzeller): In the test as written, this should not work, as 'vara'
// is of type module a, so it should complain about a null definition. However,
// the renamable range actually returns something useful.
// (verify: is this #1678 fixing it ?)
TEST(SymbolTableHandlerTest,
     FindRenamableRangeAtCursorReturnsNullDefinitionUnknown) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content = "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");
  verible::lsp::PrepareRenameParams parameters;
  parameters.textDocument.uri =
      verible::lsp::PathToLSPUri(sources_dir + "/b.sv");
  parameters.position.line = 3;  // pointing to 'vara'
  parameters.position.character = 5;

  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // Add trackers for the files we're going to process - normally done by the
  // LSP but we don't have one
  auto b_buffer = verible::lsp::EditTextBuffer(kSampleModuleB);
  parsed_buffers.GetSubscriptionCallback()(parameters.textDocument.uri,
                                           &b_buffer);
  symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_TRUE(parsed_buffers.FindBufferTrackerOrNull(
                  parameters.textDocument.uri) != nullptr);

  std::optional<verible::lsp::Range> edit_range =
      symbol_table_handler.FindRenameableRangeAtCursor(parameters,
                                                       parsed_buffers);

  // This was ASSERT_FALSE(), but in fact we get the range of 'vara' back,
  // and renaming that actually works. TODO: Check intent of this test.
  ASSERT_TRUE(edit_range.has_value());
}

TEST(SymbolTableHandlerTest, FindRenamableRangeAtCursorReturnsLocation) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");
  verible::lsp::PrepareRenameParams parameters;
  parameters.textDocument.uri =
      verible::lsp::PathToLSPUri(sources_dir + "/a.sv");
  parameters.position.line = 1;
  parameters.position.character = 11;

  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // Add trackers for the files we're going to process - normally done by the
  // LSP but we don't have one
  auto a_buffer = verible::lsp::EditTextBuffer(kSampleModuleA);
  parsed_buffers.GetSubscriptionCallback()(parameters.textDocument.uri,
                                           &a_buffer);
  symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_TRUE(parsed_buffers.FindBufferTrackerOrNull(
                  parameters.textDocument.uri) != nullptr);

  std::optional<verible::lsp::Range> edit_range =
      symbol_table_handler.FindRenameableRangeAtCursor(parameters,
                                                       parsed_buffers);
  ASSERT_TRUE(edit_range.has_value());
  if (edit_range.has_value()) {  // Access after test. Makes .clang-tidy happy
    EXPECT_EQ(edit_range.value().start.line, 1);
    EXPECT_EQ(edit_range.value().start.character, 9);
  }
}
TEST(SymbolTableHandlerTest,
     FindRenameLocationsAndCreateEditsReturnsLocationsTest) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");
  verible::lsp::RenameParams parameters;
  parameters.textDocument.uri =
      verible::lsp::PathToLSPUri(sources_dir + "/a.sv");
  parameters.position.line = 1;
  parameters.position.character = 11;
  parameters.newName = "aaa";

  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // Add trackers for the files we're going to process - normally done by the
  // LSP but we don't have one
  auto a_buffer = verible::lsp::EditTextBuffer(kSampleModuleA);
  parsed_buffers.GetSubscriptionCallback()(parameters.textDocument.uri,
                                           &a_buffer);
  symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_TRUE(parsed_buffers.FindBufferTrackerOrNull(
                  parameters.textDocument.uri) != nullptr);

  verible::lsp::WorkspaceEdit edit_range =
      symbol_table_handler.FindRenameLocationsAndCreateEdits(parameters,
                                                             parsed_buffers);
  EXPECT_EQ(edit_range.changes[parameters.textDocument.uri].size(), 2);
  EXPECT_EQ(
      edit_range.changes[verible::lsp::PathToLSPUri(sources_dir + "/b.sv")]
          .size(),
      1);
}

TEST(SymbolTableHandlerTest,
     FindRenameLocationsAndCreateEditsReturnsLocationsOnDirtyFilesTest) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content =
      "a.sv\n"
      "b.sv\n";

  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const verible::file::testing::ScopedTestFile module_a(sources_dir,
                                                        kSampleModuleA, "a.sv");
  const verible::file::testing::ScopedTestFile module_b(sources_dir,
                                                        kSampleModuleB, "b.sv");
  verible::lsp::RenameParams parameters;
  parameters.textDocument.uri =
      verible::lsp::PathToLSPUri(sources_dir + "/a.sv");
  parameters.position.line = 1;
  parameters.position.character = 11;
  parameters.newName = "aaa";

  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // Add trackers for the files we're going to process - normally done by the
  // LSP but we don't have one
  auto a_buffer = verible::lsp::EditTextBuffer(kSampleModuleA);
  parsed_buffers.GetSubscriptionCallback()(parameters.textDocument.uri,
                                           &a_buffer);
  symbol_table_handler.BuildProjectSymbolTable();
  ASSERT_TRUE(parsed_buffers.FindBufferTrackerOrNull(
                  parameters.textDocument.uri) != nullptr);

  verible::lsp::WorkspaceEdit edit_range =
      symbol_table_handler.FindRenameLocationsAndCreateEdits(parameters,
                                                             parsed_buffers);
  EXPECT_EQ(edit_range.changes[parameters.textDocument.uri].size(), 2);
  EXPECT_EQ(
      edit_range.changes[verible::lsp::PathToLSPUri(sources_dir + "/b.sv")]
          .size(),
      1);

  parameters.newName = "bbb";

  edit_range = symbol_table_handler.FindRenameLocationsAndCreateEdits(
      parameters, parsed_buffers);
  EXPECT_EQ(edit_range.changes[parameters.textDocument.uri].size(), 2);
  EXPECT_EQ(
      edit_range.changes[verible::lsp::PathToLSPUri(sources_dir + "/b.sv")]
          .size(),
      1);
}

TEST(SymbolTableHandlerTest, UpdateWithUnparseableEditorContentRegression) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      verible::file::JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(verible::file::CreateDir(sources_dir).ok());

  absl::string_view filelist_content = "";
  const verible::file::testing::ScopedTestFile filelist(
      sources_dir, filelist_content, "verible.filelist");
  const std::string uri = verible::lsp::PathToLSPUri(sources_dir + "/a.sv");
  std::filesystem::absolute({sources_dir.begin(), sources_dir.end()}).string();
  std::shared_ptr<VerilogProject> project = std::make_shared<VerilogProject>(
      sources_dir, std::vector<std::string>(), "");
  SymbolTableHandler symbol_table_handler;
  symbol_table_handler.SetProject(project);

  verilog::BufferTrackerContainer parsed_buffers;
  parsed_buffers.AddChangeListener(
      symbol_table_handler.CreateBufferTrackerListener());

  // We want to make sure that every change updates the project file with
  // the latest content.
  //
  // The verilog_project would react badly if it gets the exact same content
  // twice, as it would want to register its string_view locations in its
  // reverse map.
  //
  // If we'd filter to only send 'last_good()' content, which stays the same
  // while we have bad content, we'd attempt to register the same range.
  // multiple times with the project.
  //
  // So walking through the sequence good content (sets current() and
  // last_good()), parse error content (sets only current(), but leaves
  // last_good() as-is), and good content again (replaces current() as well
  // as last_good()), we make sure that this sequence will work.
  // Give our file list a valid content
  auto a_buffer = verible::lsp::EditTextBuffer(kSampleModuleA);
  a_buffer.set_last_global_version(1);
  parsed_buffers.GetSubscriptionCallback()(uri, &a_buffer);

  // Now, the content in the editor becomes invalid.
  auto broken_buffer = verible::lsp::EditTextBuffer("invalid-file");
  broken_buffer.set_last_global_version(2);
  parsed_buffers.GetSubscriptionCallback()(uri, &broken_buffer);

  // ... back to a valid parsed file. This replaces the previously broken file.
  a_buffer.set_last_global_version(3);
  parsed_buffers.GetSubscriptionCallback()(uri, &a_buffer);
}

TEST(SymbolTableHandlerTest, MissingVerilogProject) {
  SymbolTableHandler symbol_table_handler;
  std::vector<absl::Status> diagnostics =
      symbol_table_handler.BuildProjectSymbolTable();

  ASSERT_EQ(diagnostics.size(), 1);
  ASSERT_FALSE(diagnostics[0].ok());
}

}  // namespace
}  // namespace verilog
