// 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/dependencies.h"

#include "absl/status/status.h"
#include "common/util/file_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace verilog {
namespace {

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

TEST(FileDependenciesTest, EmptyData) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());
  VerilogProject project(sources_dir, {/* no include paths */});

  // no files
  SymbolTable symbol_table(&project);

  {  // pre-build should be empty
    FileDependencies file_deps(symbol_table);
    EXPECT_TRUE(file_deps.Empty()) << file_deps;
  }

  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  {  // post-build should be empty
    FileDependencies file_deps(symbol_table);
    EXPECT_TRUE(file_deps.Empty()) << file_deps;
  }
}

TEST(FileDependenciesTest, OneFileNoDeps) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  // None of these test cases will yield any inter-file deps.
  constexpr absl::string_view kTestCases[] = {
      "",
      // one module
      "module mmm;\n"
      "endmodule\n",
      // two modules, with dependency
      "module mmm;\n"
      "endmodule\n"
      "module ppp;\n"
      "  mmm mmm_inst();\n"
      "endmodule\n",
      // parameters with dependency
      "localparam int foo = 0;\n"
      "localparam int bar = foo + 1;\n",
  };

  for (const auto& code : kTestCases) {
    VLOG(1) << "code: " << code;
    VerilogProject project(sources_dir, {/* no include paths */});

    ScopedTestFile tf(sources_dir, code);
    {
      const auto status_or_file =
          project.OpenTranslationUnit(Basename(tf.filename()));
      ASSERT_TRUE(status_or_file.ok()) << status_or_file.status().message();
    }

    SymbolTable symbol_table(&project);
    std::vector<absl::Status> build_diagnostics;
    symbol_table.Build(&build_diagnostics);
    EXPECT_TRUE(build_diagnostics.empty());

    // post-build should be empty
    FileDependencies file_deps(symbol_table);
    EXPECT_TRUE(file_deps.Empty()) << file_deps;
  }
}

TEST(FileDependenciesTest, TwoFilesNoDeps) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include paths */});

  ScopedTestFile tf1(sources_dir, "localparam int foo = 0;");
  const auto status_or_file1 =
      project.OpenTranslationUnit(Basename(tf1.filename()));

  ScopedTestFile tf2(sources_dir, "localparam int bar = 2;");
  const auto status_or_file2 =
      project.OpenTranslationUnit(Basename(tf2.filename()));

  SymbolTable symbol_table(&project);
  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  // post-build should be empty
  FileDependencies file_deps(symbol_table);
  EXPECT_TRUE(file_deps.Empty()) << file_deps;
}

struct SymbolTableDebug {
  const SymbolTable& symbol_table;
};

static std::ostream& operator<<(std::ostream& stream,
                                const SymbolTableDebug& p) {
  stream << "Definitions:" << std::endl;
  p.symbol_table.PrintSymbolDefinitions(stream) << std::endl;
  stream << "References:" << std::endl;
  return p.symbol_table.PrintSymbolReferences(stream) << std::endl;
}

TEST(FileDependenciesTest, TwoFilesWithParamDepAtRootScope) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include paths */});

  ScopedTestFile tf1(sources_dir, "localparam int zzz = 0;\n");
  const auto status_or_file1 =
      project.OpenTranslationUnit(Basename(tf1.filename()));
  const VerilogSourceFile* file1 = *status_or_file1;

  ScopedTestFile tf2(sources_dir, "localparam int yyy = zzz * 2;\n");
  const auto status_or_file2 =
      project.OpenTranslationUnit(Basename(tf2.filename()));
  const VerilogSourceFile* file2 = *status_or_file2;

  SymbolTable symbol_table(&project);
  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  FileDependencies file_deps(symbol_table);

  // "zzz" is defined in the same $root scope, but different files,
  // so we expect a dependency edge.
  EXPECT_FALSE(file_deps.Empty()) << file_deps;
  EXPECT_EQ(file_deps.file_deps.size(), 1) << SymbolTableDebug{symbol_table};
  const auto found_ref = file_deps.file_deps.find(file2);
  ASSERT_NE(found_ref, file_deps.file_deps.end())
      << file2->GetTextStructure()->Contents();
  const auto found_def = found_ref->second.find(file1);
  ASSERT_NE(found_def, found_ref->second.end())
      << file1->GetTextStructure()->Contents();
  EXPECT_THAT(found_def->second, ElementsAre("zzz"));
}

TEST(FileDependenciesTest, TwoFilesWithParamDep) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include paths */});

  ScopedTestFile tf1(sources_dir,
                     "localparam int foo = 0;\n"
                     "package p_pkg;\n"
                     "  localparam int goo = 1;\n"
                     "endpackage\n");
  const auto status_or_file1 =
      project.OpenTranslationUnit(Basename(tf1.filename()));
  const VerilogSourceFile* file1 = *status_or_file1;

  ScopedTestFile tf2(sources_dir,
                     "localparam int bar = foo - 2;\n"
                     "localparam int baz = p_pkg::goo;\n");
  const auto status_or_file2 =
      project.OpenTranslationUnit(Basename(tf2.filename()));
  const VerilogSourceFile* file2 = *status_or_file2;

  SymbolTable symbol_table(&project);
  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  FileDependencies file_deps(symbol_table);

  EXPECT_FALSE(file_deps.Empty()) << file_deps;
  EXPECT_EQ(file_deps.file_deps.size(), 1) << SymbolTableDebug{symbol_table};
  const auto found_ref = file_deps.file_deps.find(file2);
  ASSERT_NE(found_ref, file_deps.file_deps.end())
      << file2->GetTextStructure()->Contents();
  const auto found_def = found_ref->second.find(file1);
  ASSERT_NE(found_def, found_ref->second.end())
      << file1->GetTextStructure()->Contents();
  EXPECT_THAT(found_def->second, ElementsAre("foo", "p_pkg"));
}

TEST(FileDependenciesTest, TwoFilesWithCyclicDep) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include paths */});

  ScopedTestFile tf1(sources_dir,
                     "localparam int foo = 0;\n"
                     "package p_pkg;\n"
                     "  localparam int goo = bar;\n"
                     "endpackage\n");
  const auto status_or_file1 =
      project.OpenTranslationUnit(Basename(tf1.filename()));
  const VerilogSourceFile* file1 = *status_or_file1;

  ScopedTestFile tf2(sources_dir,
                     "localparam int bar = foo - 2;\n"
                     "localparam int baz = p_pkg::goo;\n");
  const auto status_or_file2 =
      project.OpenTranslationUnit(Basename(tf2.filename()));
  const VerilogSourceFile* file2 = *status_or_file2;

  SymbolTable symbol_table(&project);
  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  FileDependencies file_deps(symbol_table);

  EXPECT_FALSE(file_deps.Empty()) << file_deps;
  {  // dependencies in one direction
    const auto found_ref = file_deps.file_deps.find(file2);
    ASSERT_NE(found_ref, file_deps.file_deps.end())
        << file2->GetTextStructure()->Contents();
    const auto found_def = found_ref->second.find(file1);
    ASSERT_NE(found_def, found_ref->second.end())
        << file1->GetTextStructure()->Contents();
    EXPECT_THAT(found_def->second, ElementsAre("foo", "p_pkg"));
  }
  {  // dependencies in reverse direction
    const auto found_ref = file_deps.file_deps.find(file1);
    ASSERT_NE(found_ref, file_deps.file_deps.end())
        << file1->GetTextStructure()->Contents();
    const auto found_def = found_ref->second.find(file2);
    ASSERT_NE(found_def, found_ref->second.end())
        << file2->GetTextStructure()->Contents();
    EXPECT_THAT(found_def->second, ElementsAre("bar"));
  }
}

TEST(FileDependenciesTest, ModuleDiamondDependencies) {
  const auto tempdir = ::testing::TempDir();
  const std::string sources_dir = JoinPath(tempdir, __FUNCTION__);
  ASSERT_TRUE(CreateDir(sources_dir).ok());

  VerilogProject project(sources_dir, {/* no include paths */});

  // 4 files: with a diamond dependency relationship
  ScopedTestFile mmm(sources_dir,
                     "module mmm;\n"
                     "  ppp ppp_i();\n"
                     "  qqq qqq_i();\n"
                     "endmodule\n");
  const auto mmm_status_or_file =
      project.OpenTranslationUnit(Basename(mmm.filename()));
  const VerilogSourceFile* mmm_file = *mmm_status_or_file;

  ScopedTestFile ppp(sources_dir,
                     "module ppp;\n"
                     "  rrr rrr_i();\n"
                     "endmodule\n");
  const auto ppp_status_or_file =
      project.OpenTranslationUnit(Basename(ppp.filename()));
  const VerilogSourceFile* ppp_file = *ppp_status_or_file;

  ScopedTestFile qqq(sources_dir,
                     "module qqq;\n"
                     "  rrr rrr_i();\n"
                     "endmodule\n");
  const auto qqq_status_or_file =
      project.OpenTranslationUnit(Basename(qqq.filename()));
  const VerilogSourceFile* qqq_file = *qqq_status_or_file;

  ScopedTestFile rrr(sources_dir,
                     "module rrr;\n"
                     "  wire w;\n"
                     "endmodule\n");
  const auto rrr_status_or_file =
      project.OpenTranslationUnit(Basename(rrr.filename()));
  const VerilogSourceFile* rrr_file = *rrr_status_or_file;

  SymbolTable symbol_table(&project);
  std::vector<absl::Status> build_diagnostics;
  symbol_table.Build(&build_diagnostics);
  EXPECT_TRUE(build_diagnostics.empty());

  FileDependencies file_deps(symbol_table);

  EXPECT_FALSE(file_deps.Empty()) << file_deps;
  // Verify 4 edges in graph.
  {
    const auto found_ref = file_deps.file_deps.find(mmm_file);
    ASSERT_NE(found_ref, file_deps.file_deps.end())
        << mmm_file->GetTextStructure()->Contents();
    {
      // mmm -> ppp
      const auto found_def = found_ref->second.find(ppp_file);
      ASSERT_NE(found_def, found_ref->second.end())
          << ppp_file->GetTextStructure()->Contents();
      EXPECT_THAT(found_def->second, ElementsAre("ppp"));
    }
    {
      // mmm -> qqq
      const auto found_def = found_ref->second.find(qqq_file);
      ASSERT_NE(found_def, found_ref->second.end())
          << qqq_file->GetTextStructure()->Contents();
      EXPECT_THAT(found_def->second, ElementsAre("qqq"));
    }
  }
  {  // ppp -> rrr
    const auto found_ref = file_deps.file_deps.find(ppp_file);
    ASSERT_NE(found_ref, file_deps.file_deps.end())
        << ppp_file->GetTextStructure()->Contents();

    const auto found_def = found_ref->second.find(rrr_file);
    ASSERT_NE(found_def, found_ref->second.end())
        << rrr_file->GetTextStructure()->Contents();
    EXPECT_THAT(found_def->second, ElementsAre("rrr"));
  }
  {
    // qqq -> rrr
    const auto found_ref = file_deps.file_deps.find(qqq_file);
    ASSERT_NE(found_ref, file_deps.file_deps.end())
        << qqq_file->GetTextStructure()->Contents();

    const auto found_def = found_ref->second.find(rrr_file);
    ASSERT_NE(found_def, found_ref->second.end())
        << rrr_file->GetTextStructure()->Contents();
    EXPECT_THAT(found_def->second, ElementsAre("rrr"));
  }
}

}  // namespace
}  // namespace verilog
