// 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 "verilog/analysis/verilog_project.h"

#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "common/text/text_structure.h"
#include "common/util/file_util.h"
#include "common/util/logging.h"
#include "common/util/range.h"
#include "gtest/gtest.h"
#include "verilog/CST/module.h"
#include "verilog/analysis/verilog_analyzer.h"

namespace verilog {
namespace {

using verible::TextStructureView;
using verible::file::Basename;
using verible::file::CreateDir;
using verible::file::JoinPath;
using verible::file::testing::ScopedTestFile;

class TempDirFile : public ScopedTestFile {
 public:
  explicit TempDirFile(absl::string_view content)
      : ScopedTestFile(::testing::TempDir(), content) {}
};

TEST(VerilogSourceFileTest, Initialization) {
  const VerilogSourceFile file("a.sv", "x/y/a.sv", "");
  // no attempt to open this file yet
  EXPECT_EQ(file.ReferencedPath(), "a.sv");
  EXPECT_EQ(file.ResolvedPath(), "x/y/a.sv");
  EXPECT_TRUE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), nullptr);
}

TEST(VerilogSourceFileTest, OpenExistingFile) {
  constexpr absl::string_view text("localparam int p = 1;\n");
  TempDirFile tf(text);
  const absl::string_view basename(Basename(tf.filename()));
  VerilogSourceFile file(basename, tf.filename(), "");
  EXPECT_TRUE(file.Open().ok());
  EXPECT_TRUE(file.Status().ok());
  EXPECT_EQ(file.ReferencedPath(), basename);
  EXPECT_EQ(file.ResolvedPath(), tf.filename());
  const absl::string_view owned_string_range(file.GetContent());
  EXPECT_EQ(owned_string_range, text);

  // Re-opening doesn't change anything
  EXPECT_TRUE(file.Open().ok());
  EXPECT_TRUE(file.Status().ok());
  EXPECT_TRUE(verible::BoundsEqual(file.GetContent(), owned_string_range));
}

TEST(VerilogSourceFileTest, NonExistingFile) {
  VerilogSourceFile file("aa.sv", "/does/not/exist/aa.sv", "");
  EXPECT_FALSE(file.Open().ok());
  EXPECT_FALSE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), nullptr);
  // Still not there.
  EXPECT_FALSE(file.Open().ok());
  EXPECT_FALSE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), nullptr);
}

TEST(VerilogSourceFileTest, ParseValidFile) {
  constexpr absl::string_view text("localparam int p = 1;\n");
  TempDirFile tf(text);
  const absl::string_view basename(Basename(tf.filename()));
  VerilogSourceFile file(basename, tf.filename(), "");
  // Parse automatically opens.
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
  const auto *tokens = &text_structure->TokenStream();
  EXPECT_NE(tokens, nullptr);
  const auto *tree = &text_structure->SyntaxTree();
  EXPECT_NE(tree, nullptr);

  // Re-parsing doesn't change anything
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), text_structure);
  EXPECT_EQ(&text_structure->TokenStream(), tokens);
  EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(VerilogSourceFileTest, ParseInvalidFile) {
  constexpr absl::string_view text("localparam 1 = p;\n");
  TempDirFile tf(text);
  const absl::string_view basename(Basename(tf.filename()));
  VerilogSourceFile file(basename, tf.filename(), "");
  // Parse automatically opens.
  EXPECT_FALSE(file.Parse().ok());
  EXPECT_FALSE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
  const auto *tokens = &text_structure->TokenStream();
  EXPECT_NE(tokens, nullptr);
  const auto *tree = &text_structure->SyntaxTree();
  EXPECT_NE(tree, nullptr);
  // but syntax tree may be empty, depends on error-recovery

  // Re-parsing doesn't change anything
  EXPECT_FALSE(file.Parse().ok());
  EXPECT_FALSE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), text_structure);
  EXPECT_EQ(&text_structure->TokenStream(), tokens);
  EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(VerilogSourceFileTest, StreamPrint) {
  constexpr absl::string_view text("localparam foo = bar;\n");
  TempDirFile tf(text);
  const absl::string_view basename(Basename(tf.filename()));
  VerilogSourceFile file(basename, tf.filename(), "");

  {
    std::ostringstream stream;
    stream << file;
    const std::string str(stream.str());
    EXPECT_TRUE(
        absl::StrContains(str, absl::StrCat("referenced path: ", basename)));
    EXPECT_TRUE(
        absl::StrContains(str, absl::StrCat("resolved path: ", tf.filename())));
    EXPECT_TRUE(absl::StrContains(str, "status: ok"));
    EXPECT_TRUE(absl::StrContains(str, "have text structure? no"));
  }

  {  // After parsng, we have a text structure.
    EXPECT_TRUE(file.Parse().ok());
    std::ostringstream stream;
    stream << file;
    const std::string str(stream.str());
    EXPECT_TRUE(absl::StrContains(str, "have text structure? yes"));
  }
}

TEST(InMemoryVerilogSourceFileTest, ParseValidFile) {
  constexpr absl::string_view text("localparam int p = 1;\n");
  InMemoryVerilogSourceFile file("/not/using/file/system.v", text);
  // Parse automatically opens.
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
  const auto *tokens = &text_structure->TokenStream();
  EXPECT_NE(tokens, nullptr);
  const auto *tree = &text_structure->SyntaxTree();
  EXPECT_NE(tree, nullptr);

  // Re-parsing doesn't change anything
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), text_structure);
  EXPECT_EQ(&text_structure->TokenStream(), tokens);
  EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(InMemoryVerilogSourceFileTest, ParseInvalidFile) {
  constexpr absl::string_view text("class \"dismissed\"!\n");
  InMemoryVerilogSourceFile file("/not/using/file/system.v", text);
  // Parse automatically opens.
  EXPECT_FALSE(file.Parse().ok());
  EXPECT_FALSE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
  const auto *tokens = &text_structure->TokenStream();
  EXPECT_NE(tokens, nullptr);
  const auto *tree = &text_structure->SyntaxTree();
  EXPECT_NE(tree, nullptr);
  // but syntax tree may be empty, depends on error-recovery

  // Re-parsing doesn't change anything
  EXPECT_FALSE(file.Parse().ok());
  EXPECT_FALSE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), text_structure);
  EXPECT_EQ(&text_structure->TokenStream(), tokens);
  EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(ParsedVerilogSourceFileTest, PreparsedValidFile) {
  constexpr absl::string_view text("localparam int p = 1;\n");
  std::unique_ptr<VerilogAnalyzer> analyzed_structure =
      std::make_unique<VerilogAnalyzer>(text, "internal");
  absl::Status status = analyzed_structure->Analyze();
  EXPECT_TRUE(status.ok());

  ParsedVerilogSourceFile file("internal", "resolved", *analyzed_structure);
  // Parse automatically opens.
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  EXPECT_EQ(&analyzed_structure->Data(), text_structure);
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
  const auto *tokens = &text_structure->TokenStream();
  EXPECT_NE(tokens, nullptr);
  const auto *tree = &text_structure->SyntaxTree();
  EXPECT_NE(tree, nullptr);

  // Re-parsing doesn't change anything
  EXPECT_TRUE(file.Parse().ok());
  EXPECT_TRUE(file.Status().ok());
  EXPECT_EQ(file.GetTextStructure(), text_structure);
  EXPECT_EQ(&text_structure->TokenStream(), tokens);
  EXPECT_EQ(&text_structure->SyntaxTree(), tree);
}

TEST(ParsedVerilogSourceFileTest, PreparsedInvalidValidFile) {
  constexpr absl::string_view text("localp_TYPO_aram int p = 1;\n");
  std::unique_ptr<VerilogAnalyzer> analyzed_structure =
      std::make_unique<VerilogAnalyzer>(text, "internal");
  absl::Status status = analyzed_structure->Analyze();
  EXPECT_FALSE(status.ok());

  ParsedVerilogSourceFile file("internal", "resolved", *analyzed_structure);
  EXPECT_TRUE(file.Open().ok());    // Already successfully implicitly opened.
  EXPECT_FALSE(file.Parse().ok());  // We expect the same parse failure.
  EXPECT_FALSE(file.Status().ok());
  const TextStructureView *text_structure =
      ABSL_DIE_IF_NULL(file.GetTextStructure());
  EXPECT_EQ(&analyzed_structure->Data(), text_structure);
  const absl::string_view owned_string_range(text_structure->Contents());
  EXPECT_EQ(owned_string_range, text);
}

TEST(VerilogProjectTest, NonexistentTranslationUnit) {
  const auto tempdir = ::testing::TempDir();
  VerilogProject project(tempdir, {tempdir});
  const auto status_or_file = project.OpenTranslationUnit("never-there.v");
  EXPECT_FALSE(status_or_file.ok());
}

TEST(VerilogProjectTest, NonexistentIncludeFile) {
  const auto tempdir = ::testing::TempDir();
  VerilogProject project(tempdir, {tempdir});
  const auto status_or_file = project.OpenIncludedFile("nope.svh");
  EXPECT_FALSE(status_or_file.ok());
}

TEST(VerilogProjectTest, NonexistentFileLookup) {
  const auto tempdir = ::testing::TempDir();
  VerilogProject project(tempdir, {tempdir});
  {  // non-const-lookup overload
    VerilogSourceFile *file = project.LookupRegisteredFile("never-there.v");
    EXPECT_EQ(file, nullptr);
  }
  {
    // const-lookup overload
    const VerilogProject &cproject(project);
    const VerilogSourceFile *file =
        cproject.LookupRegisteredFile("never-there.v");
    EXPECT_EQ(file, nullptr);
  }
}

TEST(VerilogProjectTest, UpdateFileContents) {
  // The update file content is used typically by the language server.
  // By default, we load a file from the filesystem unless we get it from the
  // editor, which then overrides it. If removed, we should fall back to file
  // contents.
  const auto tempdir = ::testing::TempDir();
  const std::string project_root_dir = JoinPath(tempdir, "srcs");
  EXPECT_TRUE(CreateDir(project_root_dir).ok());

  // root is director with sources.
  VerilogProject project(project_root_dir, {});

  // Prepare file to be auto-loaded later
  constexpr absl::string_view file_content("module foo();\nendmodule\n");
  const ScopedTestFile tf(project_root_dir, file_content);
  const absl::string_view reference_name = Basename(tf.filename());

  VerilogSourceFile *from_file;
  absl::string_view search_substring;

  // Push a local analyzed name under the name of the file.
  constexpr absl::string_view external_content("localparam int p = 1;\n");
  std::unique_ptr<VerilogAnalyzer> analyzed_structure =
      std::make_unique<VerilogAnalyzer>(external_content, "internal");
  project.UpdateFileContents(tf.filename(), analyzed_structure.get());

  // Look up the file and see that content is the external content
  from_file = *project.OpenTranslationUnit(reference_name);
  EXPECT_EQ(from_file->GetContent(), external_content);

  // ... and we find our file given the substring.
  search_substring = from_file->GetContent().substr(5);
  EXPECT_EQ(project.LookupFileOrigin(search_substring), from_file);

  // Updating with empty content, i.e. removing the memory virtual file
  // force reading from file.
  project.UpdateFileContents(tf.filename(), nullptr);

  // Should be file content.
  from_file = *project.OpenTranslationUnit(reference_name);
  EXPECT_EQ(from_file->GetContent(), file_content);

  // Looking up by the old substring should not find anything anymore.
  EXPECT_EQ(project.LookupFileOrigin(search_substring), nullptr);

  // But we find our file from our substring.
  search_substring = from_file->GetContent().substr(5);
  EXPECT_EQ(project.LookupFileOrigin(search_substring), from_file);
}

TEST(VerilogProjectTest, UpdateFileContentsEmptyFile) {
  // Users can add empty files to the filelist and subsequently
  // remove them.
  const auto tempdir = ::testing::TempDir();
  const std::string project_root_dir = JoinPath(tempdir, "srcs");
  EXPECT_TRUE(CreateDir(project_root_dir).ok());

  // root is directory with sources.
  VerilogProject project(project_root_dir, {});

  // Prepare file to be auto-loaded later
  const ScopedTestFile tf(project_root_dir, "");
  const absl::string_view reference_name = Basename(tf.filename());

  // Push a local analyzed name under the name of the file.
  constexpr absl::string_view external_content("localparam int p = 1;\n");
  std::unique_ptr<VerilogAnalyzer> analyzed_structure =
      std::make_unique<VerilogAnalyzer>(external_content, "internal");
  project.UpdateFileContents(tf.filename(), analyzed_structure.get());

  // Look up the file and see that content is the external content
  VerilogSourceFile *from_file;
  absl::string_view search_substring;
  from_file = *project.OpenTranslationUnit(reference_name);
  EXPECT_EQ(from_file->GetContent(), external_content);

  // ... and we find our file given the substring.
  search_substring = from_file->GetContent().substr(5);
  EXPECT_EQ(project.LookupFileOrigin(search_substring), from_file);

  // Prepare an empty file
  constexpr absl::string_view empty_file_content("");
  const ScopedTestFile empty_file(project_root_dir, empty_file_content);
  const absl::string_view empty_file_reference =
      Basename(empty_file.filename());

  // Push the empty file into the project
  std::unique_ptr<VerilogAnalyzer> analyzed_empty_structure =
      std::make_unique<VerilogAnalyzer>(empty_file_content, "internal");
  project.UpdateFileContents(empty_file.filename(),
                             analyzed_empty_structure.get());

  // Check the content from the two files are present
  from_file = *project.OpenTranslationUnit(reference_name);
  EXPECT_EQ(from_file->GetContent(), external_content);

  from_file = *project.OpenTranslationUnit(empty_file_reference);
  EXPECT_EQ(from_file->GetContent(), empty_file_content);

  // Remove the empty file
  project.UpdateFileContents(empty_file.filename(), nullptr);

  // Make sure the remaining file is still present
  from_file = *project.OpenTranslationUnit(reference_name);
  EXPECT_EQ(from_file->GetContent(), external_content);

  // Make sure the empty file was removed
  EXPECT_EQ(project.LookupFileOrigin(empty_file.filename()), nullptr);
}

TEST(VerilogProjectTest, LookupFileOriginTest) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  VerilogProject project(sources_dir, {});
  // no files yet

  {
    constexpr absl::string_view foreign_text("not from any file");
    EXPECT_EQ(project.LookupFileOrigin(foreign_text), nullptr);
  }

  // Add one file.  Don't even need to parse it.
  const ScopedTestFile tf(sources_dir, "module m;\nendmodule\n");
  const auto status_or_file =
      project.OpenTranslationUnit(Basename(tf.filename()));
  VerilogSourceFile *verilog_source_file = *status_or_file;
  const absl::string_view content1(verilog_source_file->GetContent());

  {
    constexpr absl::string_view foreign_text("still not from any file");
    EXPECT_EQ(project.LookupFileOrigin(foreign_text), nullptr);
  }

  // Pick a substring known to come from that file.
  EXPECT_EQ(project.LookupFileOrigin(content1.substr(2, 4)),
            verilog_source_file);

  // Add one more file.
  const ScopedTestFile tf2(sources_dir, "class c;\nendclass\n");
  const auto status_or_file2 =
      project.OpenTranslationUnit(Basename(tf2.filename()));
  VerilogSourceFile *verilog_source_file2 = *status_or_file2;
  const absl::string_view content2(verilog_source_file2->GetContent());

  // Pick substrings known to come from those files.
  EXPECT_EQ(project.LookupFileOrigin(content1.substr(5, 5)),
            verilog_source_file);
  EXPECT_EQ(project.LookupFileOrigin(content2.substr(9, 4)),
            verilog_source_file2);
}

TEST(VerilogProjectTest, LookupFileOriginTestMoreFiles) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir =
      JoinPath(tempdir, "LookupFileOriginTestMoreFiles");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  VerilogProject project(sources_dir, {});
  // no files yet

  constexpr absl::string_view foreign_text("not from any file");

  // WArning: Test size is quadratic in N, but linear in memory in N.
  constexpr int N = 50;
  std::vector<std::unique_ptr<ScopedTestFile>> test_files;
  std::vector<const VerilogSourceFile *> sources;
  for (int i = 0; i < N; ++i) {
    // Write files, need not be parse-able.
    test_files.emplace_back(std::make_unique<ScopedTestFile>(
        sources_dir, "sa89*(98<Na! 89 89891231!@#ajk jasoij(*&^ asaissd0afd "));
    const auto status_or_file =
        project.OpenTranslationUnit(Basename(test_files.back()->filename()));
    const VerilogSourceFile *source_file = *status_or_file;
    ASSERT_NE(source_file, nullptr);
    sources.push_back(source_file);

    for (const auto &source : sources) {
      // Pick substrings known to come from those files.
      EXPECT_EQ(project.LookupFileOrigin(source->GetContent().substr(15, 12)),
                source);
    }
    EXPECT_EQ(project.LookupFileOrigin(foreign_text), nullptr);
  }
}

TEST(VerilogProjectTest, ValidTranslationUnit) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  constexpr absl::string_view text("module m;\nendmodule\n");
  const ScopedTestFile tf(sources_dir, text);
  const auto status_or_file =
      project.OpenTranslationUnit(Basename(tf.filename()));
  VerilogSourceFile *verilog_source_file = *status_or_file;
  EXPECT_TRUE(verilog_source_file->Status().ok());
  EXPECT_EQ(verilog_source_file->ReferencedPath(), Basename(tf.filename()));
  EXPECT_EQ(verilog_source_file->ResolvedPath(), tf.filename());
  EXPECT_EQ(project.LookupRegisteredFile(Basename(tf.filename())),
            verilog_source_file);
  const absl::string_view content(verilog_source_file->GetContent());
  {  // const-lookup overload
    const VerilogProject &cproject(project);
    EXPECT_EQ(cproject.LookupRegisteredFile(Basename(tf.filename())),
              verilog_source_file);
    EXPECT_EQ(cproject.LookupFileOrigin(content.substr(2, 4)),
              verilog_source_file);
  }

  EXPECT_TRUE(verilog_source_file->Parse().ok());
  const TextStructureView &text_structure(
      *verilog_source_file->GetTextStructure());
  const auto *tree = ABSL_DIE_IF_NULL(text_structure.SyntaxTree().get());
  EXPECT_EQ(FindAllModuleDeclarations(*tree).size(), 1);

  {
    // Re-parsing the file changes nothing.
    EXPECT_TRUE(verilog_source_file->Parse().ok());
    const auto *tree2 = ABSL_DIE_IF_NULL(text_structure.SyntaxTree().get());
    EXPECT_EQ(tree2, tree);
    EXPECT_EQ(FindAllModuleDeclarations(*tree).size(), 1);
  }
  {  // Re-opening the file changes nothing.
    const auto status_or_file2 =
        project.OpenTranslationUnit(Basename(tf.filename()));
    VerilogSourceFile *verilog_source_file2 = *status_or_file2;
    EXPECT_EQ(verilog_source_file2, verilog_source_file);
    EXPECT_TRUE(verilog_source_file2->Status().ok());
  }

  // Testing begin/end iteration.
  for (auto &file : project) {
    EXPECT_TRUE(file.second->Parse().ok());
  }
  for (const auto &file : project) {
    EXPECT_TRUE(file.second->Status().ok());
  }
}

TEST(VerilogProjectTest, ValidIncludeFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  constexpr absl::string_view text("`define FOO 1\n");
  const ScopedTestFile tf(includes_dir, text);
  const absl::string_view basename(Basename(tf.filename()));
  const auto status_or_file = project.OpenIncludedFile(basename);
  VerilogSourceFile *verilog_source_file = *status_or_file;
  EXPECT_TRUE(verilog_source_file->Status().ok());
  EXPECT_EQ(verilog_source_file->ReferencedPath(), basename);
  EXPECT_EQ(verilog_source_file->ResolvedPath(), tf.filename());
  EXPECT_EQ(project.LookupRegisteredFile(Basename(tf.filename())),
            verilog_source_file);
  {  // const-lookup overload
    const VerilogProject &cproject(project);
    EXPECT_EQ(cproject.LookupRegisteredFile(Basename(tf.filename())),
              verilog_source_file);
  }

  // Re-opening same file, changes nothing
  {
    const auto status_or_file2 = project.OpenIncludedFile(basename);
    VerilogSourceFile *verilog_source_file2 = *status_or_file2;
    EXPECT_EQ(verilog_source_file2, verilog_source_file);
    EXPECT_TRUE(verilog_source_file2->Status().ok());
  }

  // includes aren't required to be parse-able, so just open
  EXPECT_TRUE(verilog_source_file->Open().ok());
  EXPECT_FALSE(verilog_source_file->GetContent().empty());

  // re-opening the file changes nothing
  EXPECT_TRUE(verilog_source_file->Open().ok());
  EXPECT_FALSE(verilog_source_file->GetContent().empty());
}

TEST(VerilogProjectTest, OpenVirtualIncludeFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  constexpr absl::string_view text("`define FOO 1\n");
  const std::string basename = "virtual_include_file1";
  const std::string full_path = JoinPath(includes_dir, basename);
  // The virtual file is added by its full path. But the include is opened by
  // the basename.
  project.AddVirtualFile(full_path, text);

  const auto status_or_file = project.OpenIncludedFile(basename);
  VerilogSourceFile *verilog_source_file = *status_or_file;
  EXPECT_TRUE(verilog_source_file->Status().ok());
  EXPECT_EQ(verilog_source_file->ReferencedPath(), full_path);
  EXPECT_EQ(verilog_source_file->ResolvedPath(), full_path);
  EXPECT_EQ(project.LookupRegisteredFile(basename), verilog_source_file);
  {  // const-lookup overload
    const VerilogProject &cproject(project);
    EXPECT_EQ(cproject.LookupRegisteredFile(basename), verilog_source_file);
  }

  // Re-opening same file, changes nothing
  {
    const auto status_or_file2 = project.OpenIncludedFile(basename);
    VerilogSourceFile *verilog_source_file2 = *status_or_file2;
    EXPECT_EQ(verilog_source_file2, verilog_source_file);
    EXPECT_TRUE(verilog_source_file2->Status().ok());
  }

  // includes aren't required to be parse-able, so just open
  EXPECT_TRUE(verilog_source_file->Open().ok());
  EXPECT_FALSE(verilog_source_file->GetContent().empty());

  // re-opening the file changes nothing
  EXPECT_TRUE(verilog_source_file->Open().ok());
  EXPECT_FALSE(verilog_source_file->GetContent().empty());
}

TEST(VerilogProjectTest, TranslationUnitNotFound) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  constexpr absl::string_view text("module m;\nendmodule\n");
  // deliberately plant this file in the includes dir != sources dir
  const ScopedTestFile tf(includes_dir, text);
  {
    const auto status_or_file =
        project.OpenTranslationUnit(Basename(tf.filename()));
    EXPECT_FALSE(status_or_file.ok());
  }
  {  // try again, still fail
    const auto status_or_file =
        project.OpenTranslationUnit(Basename(tf.filename()));
    EXPECT_FALSE(status_or_file.ok());
  }
}

TEST(VerilogProjectTest, IncludeFileNotFound) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  constexpr absl::string_view text("module m;\nendmodule\n");
  // deliberately plant this file in the sources dir != include dir
  const ScopedTestFile tf(sources_dir, text);
  {
    const auto status_or_file =
        project.OpenIncludedFile(Basename(tf.filename()));
    EXPECT_FALSE(status_or_file.ok());
  }
  {  // try again, still fail
    const auto status_or_file =
        project.OpenIncludedFile(Basename(tf.filename()));
    EXPECT_FALSE(status_or_file.ok());
  }
}

TEST(VerilogProjectTest, AddVirtualFile) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, "srcs");
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(sources_dir).ok());
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  VerilogProject project(sources_dir, {includes_dir});

  const std::string file_path = "/some/file";
  const std::string file_content = "virtual file content";
  project.AddVirtualFile(file_path, file_content);

  auto *stored_file = project.LookupRegisteredFile(file_path);
  ASSERT_NE(stored_file, nullptr);
  EXPECT_TRUE(stored_file->Open().ok());
  EXPECT_TRUE(stored_file->Status().ok());
  EXPECT_EQ(stored_file->GetContent(), file_content);
}

}  // namespace
}  // namespace verilog
