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

#include <algorithm>
#include <map>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "common/text/macro_definition.h"
#include "common/text/token_info.h"
#include "common/util/container_util.h"
#include "common/util/file_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "verilog/analysis/verilog_analyzer.h"
#include "verilog/analysis/verilog_project.h"
#include "verilog/parser/verilog_lexer.h"
#include "verilog/parser/verilog_token_enum.h"

namespace verilog {
namespace {

using testing::ElementsAre;
using testing::Pair;
using testing::StartsWith;
using verible::container::FindOrNull;
using verible::file::CreateDir;
using verible::file::JoinPath;
using verible::file::testing::ScopedTestFile;
using FileOpener = VerilogPreprocess::FileOpener;

class LexerTester {
 public:
  LexerTester(absl::string_view text) : lexer_(text) {
    for (lexer_.DoNextToken(); !lexer_.GetLastToken().isEOF();
         lexer_.DoNextToken()) {
      lexed_sequence_.push_back(lexer_.GetLastToken());
    }
    InitTokenStreamView(lexed_sequence_, &stream_view_);
  }

  verible::TokenStreamView GetTokenStreamView() const { return stream_view_; }

 private:
  VerilogLexer lexer_;
  verible::TokenSequence lexed_sequence_;
  verible::TokenStreamView stream_view_;
};

class PreprocessorTester {
 public:
  PreprocessorTester(absl::string_view text,
                     const VerilogPreprocess::Config& config)
      : analyzer_(text, "<<inline-file>>", config),
        status_(analyzer_.Analyze()) {}

  explicit PreprocessorTester(absl::string_view text)
      : PreprocessorTester(text, VerilogPreprocess::Config()) {}

  const VerilogPreprocessData& PreprocessorData() const {
    return analyzer_.PreprocessorData();
  }

  const verible::TextStructureView& Data() const { return analyzer_.Data(); }

  const absl::Status& Status() const { return status_; }

  const VerilogAnalyzer& Analyzer() const { return analyzer_; }

 private:
  VerilogAnalyzer analyzer_;
  const absl::Status status_;
};

struct FailTest {
  absl::string_view input;
  int offset;
};
TEST(VerilogPreprocessTest, InvalidPreprocessorInputs) {
  const FailTest test_cases[] = {
      {"`define\n", 8},                      // unterminated macro definition
      {"\n\n`define\n", 10},                 // unterminated macro definition
      {"`define 789\n", 8},                  // expect identifier for macro name
      {"`define 789 non-sense\n", 8},        // expect identifier for macro name
      {"`define 789 \\\nnon-sense\n", 8},    // expect identifier for macro name
      {"`define FOO(\n", 13},                // unterminated parameter list
      {"`define FOO(234\n", 12},             // invalid parameter name
      {"`define FOO(234)\n", 12},            // invalid parameter name
      {"`define FOO(aaa\n", 16},             // unterminated parameter list
      {"`define FOO(aaa;\n", 15},            // bad parameter separator
      {"`define FOO(aaa bbb\n", 16},         // bad parameter separator
      {"`define FOO(aaa bbb)\n", 16},        // bad parameter separator
      {"`define FOO(aaa+bbb)\n", 15},        // bad parameter separator
      {"`define FOO(aaa.zzz\n", 15},         // bad parameter separator
      {"`define FOO(aaa.zzz)\n", 15},        // bad parameter separator
      {"`define FOO(aaa,\n", 17},            // unterminated parameter list
      {"`define FOO(aaa,)\n", 16},           // missing parameter name
      {"`define FOO(,,)\n", 12},             // missing parameter name
      {"`define FOO(aaa, 345)\n", 17},       // invalid parameter name
      {"`define FOO(aaa=\n", 17},            // unterminated default parameter
      {"`define FOO(aaa =\n", 18},           // unterminated default parameter
      {"`define FOO(aaa = 9\n", 20},         // expecting ',' or ')'
      {"`define FOO(aaa = 9, bbb =\n", 27},  // unterminated parameter list
      {"`define FOO(aa = 9, bb = 2\n", 27},  // expecting ',' or ')'
  };
  for (const auto& test_case : test_cases) {
    PreprocessorTester tester(test_case.input);
    EXPECT_FALSE(tester.Status().ok())
        << "Expected preprocess to fail on invalid input: \"" << test_case.input
        << "\"";
    const auto& rejected_tokens = tester.Analyzer().GetRejectedTokens();
    ASSERT_FALSE(rejected_tokens.empty())
        << "on invalid input: \"" << test_case.input << "\"";
    const int rejected_token_offset =
        rejected_tokens[0].token_info.left(tester.Analyzer().Data().Contents());
    EXPECT_EQ(rejected_token_offset, test_case.offset)
        << "on invalid input: \"" << test_case.input << "\"";
  }
}

#define EXPECT_PARSE_OK()                                                \
  do {                                                                   \
    EXPECT_TRUE(tester.Status().ok()) << "Unexpected analyzer failure."; \
    EXPECT_TRUE(tester.PreprocessorData().errors.empty());               \
    EXPECT_TRUE(tester.Analyzer().GetRejectedTokens().empty());          \
  } while (false)

// Verify that VerilogPreprocess works without any directives.
TEST(VerilogPreprocessTest, WorksWithoutDefinitions) {
  absl::string_view test_cases[] = {
      "",
      "\n",
      "module foo;\nendmodule\n",
      "module foo(input x, output y);\nendmodule\n",
  };
  for (const auto& test_case : test_cases) {
    PreprocessorTester tester(test_case);
    EXPECT_PARSE_OK();

    const auto& definitions = tester.PreprocessorData().macro_definitions;
    EXPECT_TRUE(definitions.empty());
  }
}

TEST(VerilogPreprocessTest, OneMacroDefinitionNoParamsNoValue) {
  absl::string_view test_cases[] = {
      "`define FOOOO\n",
      "`define     FOOOO\n",
      "module foo;\nendmodule\n"
      "`define FOOOO\n",
      "`define FOOOO\n"
      "module foo;\nendmodule\n",
  };
  for (const auto& test_case : test_cases) {
    PreprocessorTester tester(test_case);
    EXPECT_PARSE_OK();

    const auto& definitions = tester.PreprocessorData().macro_definitions;
    EXPECT_THAT(definitions, ElementsAre(Pair("FOOOO", testing::_)));
    auto macro = FindOrNull(definitions, "FOOOO");
    ASSERT_NE(macro, nullptr);
    EXPECT_EQ(macro->DefinitionText().text(), "");
    EXPECT_FALSE(macro->IsCallable());
    EXPECT_TRUE(macro->Parameters().empty());
  }
}

TEST(VerilogPreprocessTest, OneMacroDefinitionNoParamsSimpleValue) {
  PreprocessorTester tester(
      "module foo;\nendmodule\n"
      "`define FOOOO \"bar\"\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_THAT(definitions, ElementsAre(Pair("FOOOO", testing::_)));
  auto macro = FindOrNull(definitions, "FOOOO");
  ASSERT_NE(macro, nullptr);
  EXPECT_EQ(macro->DefinitionText().text(), "\"bar\"");
  EXPECT_FALSE(macro->IsCallable());
  EXPECT_TRUE(macro->Parameters().empty());
}

TEST(VerilogPreprocessTest, OneMacroDefinitionOneParamWithValue) {
  PreprocessorTester tester(
      "module foo;\nendmodule\n"
      "`define FOOOO(x) (x+1)\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_THAT(definitions, ElementsAre(Pair("FOOOO", testing::_)));
  auto macro = FindOrNull(definitions, "FOOOO");
  ASSERT_NE(macro, nullptr);
  EXPECT_EQ(macro->DefinitionText().text(), "(x+1)");
  EXPECT_TRUE(macro->IsCallable());
  const auto& params = macro->Parameters();
  EXPECT_EQ(params.size(), 1);
  const auto& param(params[0]);
  EXPECT_EQ(param.name.text(), "x");
  EXPECT_FALSE(param.HasDefaultText());
}

TEST(VerilogPreprocessTest, OneMacroDefinitionOneParamDefaultWithValue) {
  PreprocessorTester tester(
      "module foo;\nendmodule\n"
      "`define FOOOO(x=22) (x+3)\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_THAT(definitions, ElementsAre(Pair("FOOOO", testing::_)));
  auto macro = FindOrNull(definitions, "FOOOO");
  ASSERT_NE(macro, nullptr);
  EXPECT_EQ(macro->DefinitionText().text(), "(x+3)");
  EXPECT_TRUE(macro->IsCallable());
  const auto& params = macro->Parameters();
  EXPECT_EQ(params.size(), 1);
  const auto& param(params[0]);
  EXPECT_EQ(param.name.text(), "x");
  EXPECT_TRUE(param.HasDefaultText());
  EXPECT_EQ(param.default_value.text(), "22");
}

TEST(VerilogPreprocessTest, TwoMacroDefinitions) {
  PreprocessorTester tester(
      "`define BAAAAR(y, z) (y*z)\n"
      "`define FOOOO(x=22) (x+3)\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_THAT(definitions, ElementsAre(Pair("BAAAAR", testing::_),
                                       Pair("FOOOO", testing::_)));
  {
    auto macro = FindOrNull(definitions, "BAAAAR");
    ASSERT_NE(macro, nullptr);
    EXPECT_TRUE(macro->IsCallable());
    const auto& params = macro->Parameters();
    EXPECT_EQ(params.size(), 2);
  }
  {
    auto macro = FindOrNull(definitions, "FOOOO");
    ASSERT_NE(macro, nullptr);
    EXPECT_TRUE(macro->IsCallable());
    const auto& params = macro->Parameters();
    EXPECT_EQ(params.size(), 1);
  }
}

TEST(VerilogPreprocessTest, UndefMacro) {
  PreprocessorTester tester(
      "`define FOO 42\n"
      "`undef FOO");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_EQ(definitions.size(), 0);
}

TEST(VerilogPreprocessTest, UndefNonexistentMacro) {
  PreprocessorTester tester("`undef FOO");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_EQ(definitions.size(), 0);
  EXPECT_TRUE(tester.PreprocessorData().warnings.empty());  // not a problem.
}

TEST(VerilogPreprocessTest, RedefineMacroWarning) {
  PreprocessorTester tester(
      "`define FOO 1\n"
      "`define FOO 2\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_EQ(definitions.size(), 1);

  const auto& warnings = tester.PreprocessorData().warnings;
  EXPECT_EQ(warnings.size(), 1);
  EXPECT_EQ(warnings.front().error_message, "Re-defining macro");
}

// We might have different modes later, in which we remove the define tokens
// from the stream. Document the current default which registeres all the
// defines, but also does not filter out the define calls.
TEST(VerilogPreprocessTest, DefaultPreprocessorKeepsDefineInStream) {
  PreprocessorTester tester(
      "`define FOO\n"
      "`define BAR(x) (x)\n"
      "module x(); endmodule\n");
  EXPECT_PARSE_OK();

  const auto& definitions = tester.PreprocessorData().macro_definitions;
  EXPECT_EQ(definitions.size(), 2);

  // The original `define tokens are still in the stream
  const auto& token_stream = tester.Data().GetTokenStreamView();
  const int count_defines =
      std::count_if(token_stream.begin(), token_stream.end(),
                    [](verible::TokenSequence::const_iterator t) {
                      return t->token_enum() == verilog_tokentype::PP_define;
                    });
  EXPECT_EQ(count_defines, 2);
}

struct BranchFailTest {
  absl::string_view input;
  int offset;
  absl::string_view expected_error;
};
TEST(VerilogPreprocessTest, IncompleteOrUnbalancedIfdef) {
  const BranchFailTest test_cases[] = {
      {"`endif", 0, "Unmatched `endif"},
      {"`else", 0, "Unmatched `else"},
      {"`elsif FOO", 0, "Unmatched `elsif"},
      {"`ifdef", 6, "unexpected EOF where expecting macro name"},
      {"`ifdef FOO\n`endif\n`endif", 18, "Unmatched `endif"},
      {"`ifdef FOO\n`endif\n`else", 18, "Unmatched `else"},
      {"`ifdef FOO\n`endif\n`elsif BAR", 18, "Unmatched `elsif"},
      {"`ifdef FOO\n`else\n`else", 17, "Duplicate `else"},
      {"`ifdef FOO\n`else\n`elsif BAR", 17, "`elsif after `else"},
      {"`ifdef FOO\n`ifdef BAR`else\n`else", 27, "Duplicate `else"},
      {"`ifdef FOO\n`else\n`ifdef BAR\n`endif", 11, "Unterminated preprocess"},
      {"`ifdef FOO\n`elsif BAR\n", 11, "Unterminated preprocessing"},
      {"`ifdef FOO\n`elsif BAR\n`else\n", 22, "Unterminated preprocessing"},
  };
  for (const BranchFailTest& test : test_cases) {
    PreprocessorTester tester(
        test.input, VerilogPreprocess::Config({.filter_branches = true}));

    EXPECT_FALSE(tester.Status().ok());
    ASSERT_GE(tester.PreprocessorData().errors.size(), 1);
    const auto& error = tester.PreprocessorData().errors.front();
    EXPECT_THAT(error.error_message, StartsWith(test.expected_error));
    const int error_token_offset =
        error.token_info.left(tester.Analyzer().Data().Contents());
    EXPECT_EQ(error_token_offset, test.offset) << "Input: " << test.input;
  }
}

struct RawAndFiltered {
  absl::string_view description;
  absl::string_view pp_input;
  absl::string_view equivalent;
};
TEST(VerilogPreprocess, FilterPPBranches) {
  const RawAndFiltered test_cases[] = {
      {"[** Defined macro taking ifdef branch **]",
       R"(
`define FOO 1
`ifdef FOO
  module bar();
`else
  module quux();
`endif
  endmodule)",
       // ...equivalent to
       R"(
`define FOO 1
 module bar();
 endmodule)"},

      {"[** Undefined macro taking else branch **]",
       R"(
`ifdef FOO
  module bar();
`else
  module quux();
`endif
  endmodule)",
       // ...equivalent to
       R"(
module quux();
endmodule)"},

      {"[** Undefined macro taking else branch. defined value `undef-ed **]",
       R"(
`define FOO
`undef FOO
`ifdef FOO
  module bar();
`else
  module quux();
`endif
  endmodule)",
       // ...equivalent to
       R"(
`define FOO
`undef FOO
module quux();
endmodule)"},

      {"[** Negative logic: Defined macro taking ifndef-else branch **]",
       R"(
`define FOO 1
`ifndef FOO
  module bar();
`else
  module quux();
`endif
  endmodule)",
       // ...equivalent to
       R"(
`define FOO 1
module quux();
endmodule)"},

      {"[** Negative logic: Undefined macro taking ifndef branch **]",
       R"(
`ifndef FOO
  module bar();
`else
  module quux();
`endif
  endmodule)",
       // ...equivalent to
       R"(
module bar();
endmodule)"},

      {"[** Elsif: choice of first branch **]",
       R"(
`define FOO 1
`ifdef FOO
  module foo(); endmodule
`elsif BAR
  module bar(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define FOO 1
module foo(); endmodule)"},

      {"[** Elsif: choice of elsif branch **]",
       R"(
`define BAR 1
`ifdef FOO
  module foo(); endmodule
`elsif BAR
  module bar(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define BAR 1
module bar(); endmodule)"},

      {"[** Elsif: no branch chosen **]",
       R"(
`define BAZ 1
`ifdef FOO
  module foo(); endmodule
`elsif BAR
  module bar(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define BAZ 1
)"},

      {"[** Elsif: only first (`ifdef) matching branch chosen **]",
       R"(
`define FOO 1
`define BAR 1
`define BAZ 1
`ifdef FOO
  module foo(); endmodule
`elsif BAR
  module bar(); endmodule
`elsif BAZ
  module baz(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define FOO 1
`define BAR 1
`define BAZ 1
module foo(); endmodule
)"},

      {"[** Elsif: only first (`elsif) matching branch chosen **]",
       R"(
`define BAR 1
`define BAZ 1
`define QUUX 1

`ifdef FOO
module foo(); endmodule
`elsif BAR
module bar(); endmodule
`elsif BAZ
module baz(); endmodule
`elsif QUUX
module quux(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define BAR 1
`define BAZ 1
`define QUUX 1
module bar(); endmodule
)"},

      {"[** Nested conditions **]",
       R"(
`define BAR 1
`ifdef FOO
  module foo(); endmodule
 `ifdef BAR
   module foo_bar(); endmodule
 `else
   module foo_nonbar(); endmodule
 `endif
  module post_foo(); endmodule
`else
  module nonfoo(); endmodule
 `ifdef BAR
   module nonfoo_bar(); endmodule
 `else
   module nonfoo_nonbar(); endmodule;
 `endif
  module post_nonfoo(); endmodule
`endif)",
       // ... equivalent to
       R"(
`define BAR 1
module nonfoo(); endmodule
module nonfoo_bar(); endmodule
module post_nonfoo(); endmodule)"},

      {"[** Meta-def: Macro defined in branch controls another branch **]",
       R"(
`ifdef FOO
  `define BAR 1
  `undef FOOBAR
`else
  `define BAZ 1
  `undef FOOQUX
`endif

`ifdef BAR
module bar(); endmodule
`endif
`ifdef BAZ
module baz(); endmodule
`endif)",
       // ...equivalent to
       R"(
`define BAZ 1
`undef FOOQUX
module baz(); endmodule
)"}};

  for (const RawAndFiltered& test : test_cases) {
    PreprocessorTester with_filter(
        test.pp_input, VerilogPreprocess::Config({.filter_branches = true}));
    EXPECT_TRUE(with_filter.Status().ok())
        << with_filter.Status() << " " << test.description;
    PreprocessorTester equivalent(
        test.equivalent, VerilogPreprocess::Config({.filter_branches = false}));
    EXPECT_TRUE(equivalent.Status().ok())
        << equivalent.Status() << " " << test.description;

    const auto& filtered_stream = with_filter.Data().GetTokenStreamView();
    const auto& equivalent_stream = equivalent.Data().GetTokenStreamView();
    EXPECT_GT(filtered_stream.size(), 0) << test.description;
    EXPECT_EQ(filtered_stream.size(), equivalent_stream.size())
        << test.description;
    auto filtered_it = filtered_stream.begin();
    auto equivalent_it = equivalent_stream.begin();
    while (filtered_it != filtered_stream.end() &&
           equivalent_it != equivalent_stream.end()) {
      EXPECT_EQ((*filtered_it)->text(), (*equivalent_it)->text())
          << test.description;
      EXPECT_EQ((*filtered_it)->token_enum(), (*equivalent_it)->token_enum())
          << test.description;
      ++filtered_it;
      ++equivalent_it;
    }
  }
}

TEST(VerilogPreprocessTest, MacroExpansion) {
  const RawAndFiltered test_cases[] = {
      {"[** Multi-tokens macros being correctly parsed **]",
       R"(
`define ASSIGN1 =1
`define ASSIGN0 =0
module foo;
wire x`ASSIGN1;
wire y `ASSIGN0;
endmodule)",
       // ...equivalent to
       R"(
`define ASSIGN1 =1
`define ASSIGN0 =0
module foo;
wire x =1;
wire y =0;
endmodule)"},

      {"[** Multi-tokens macros not empty after undefing **]",
       R"(
`define XWIRE wire x
`define YWIRE wire y
module foo;
`XWIRE = 1;
`YWIRE = 0;
endmodule
`undef XWIRE
`undef YWIRE)",
       // ...equivalent to
       R"(
`define XWIRE wire x
`define YWIRE wire y
module foo;
wire x = 1;
wire y = 0;
endmodule
`undef XWIRE
`undef YWIRE)"},

      {"[** Macros that contain other macro calls, redefining the inner macro "
       "**]",
       R"(
`define XWIRE wire x
`define YWIRE wire y
`define ASSIGN1XWIRE `XWIRE = 1;
`define ASSIGN0YWIRE `YWIRE = 0;
module foo;
`ASSIGN1XWIRE
`ASSIGN0YWIRE
`define XWIRE wire new_x_wire
`ASSIGN1XWIRE
endmodule)",
       // ...equivalent to
       R"(
`define XWIRE wire x
`define YWIRE wire y
`define ASSIGN1XWIRE `XWIRE = 1;
`define ASSIGN0YWIRE `YWIRE = 0;
module foo;
wire x = 1;
wire y = 0;
`define XWIRE wire new_x_wire
wire new_x_wire = 1;
endmodule)"},

      {"[** Macros contatining back to back macro calls **]",
       R"(
`define XWIRE wire x
`define YWIRE wire y
`define ASSIGN1 = 1
`define ASSIGN0 = 0
`define ASSIGN1XWIRE `XWIRE `ASSIGN1;
`define ASSIGN0YWIRE `YWIRE `ASSIGN0;
module foo;
`ASSIGN1XWIRE
`ASSIGN0YWIRE
`define XWIRE wire new_x_wire
`ASSIGN1XWIRE
endmodule)",
       // ...equivalent to
       R"(
`define XWIRE wire x
`define YWIRE wire y
`define ASSIGN1 = 1
`define ASSIGN0 = 0
`define ASSIGN1XWIRE `XWIRE `ASSIGN1;
`define ASSIGN0YWIRE `YWIRE `ASSIGN0;
module foo;
wire x = 1;
wire y = 0;
`define XWIRE wire new_x_wire
wire new_x_wire = 1;
endmodule)"},

      {"[** Macros with formal parameters, expanded with both default value, "
       "and actual passed value **]",
       R"(
`define LSb(n=2) [n-1:0]
module testcase_ppMacro;
localparam int A = 123;
wire a = A`LSb();
wire b = A`LSb(5);
wire c = A[5-1:0];
endmodule)",
       // ...equivalent to
       R"(
`define LSb(n=2) [n-1:0]
module testcase_ppMacro;
localparam int A = 123;
wire a = A[2-1:0];
wire b = A[5-1:0];
wire c = A[5-1:0];
endmodule)"},

      {"[** Actual parameter is another macro call **]",
       R"(
`define FOO a
`define A(n) n
`define B(n=x) n ,y
module m;
wire `A(xyz);
wire `B(`FOO);
endmodule
`undef B
`undef A
`undef FOO)",
       // ...equivalent to
       R"(
`define FOO a
`define A(n) n
`define B(n=x) n ,y
module m;
wire xyz;
wire a ,y;
endmodule
`undef B
`undef A
`undef FOO)"},

      {"[** Multiple parameter macros (From 2017 SV-LRM) **]",
       R"(
`define MACRO1(a=5,b="B",c) $display(a,,b,,c);
`define MACRO2(a=5, b, c="C") $display(a,,b,,c);
`define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);
module m;
`MACRO1 ( , 2, 3 )
`MACRO1 ( 1 , , 3 )
`MACRO1 ( , 2, )
`MACRO2 (1, , 3)
`MACRO2 (, 2, )
`MACRO2 (, 2)
`MACRO3 ( 1 )
`MACRO3 ()
endmodule
`undef MACRO)",
       // ...equivalent to
       R"(
`define MACRO1(a=5,b="B",c) $display(a,,b,,c);
`define MACRO2(a=5, b, c="C") $display(a,,b,,c);
`define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);
module m;
$display(5,,2,,3);
$display(1,,"B",,3);
$display(5,,2,,);
$display(1,,,,3);
$display(5,,2,,"C");
$display(5,,2,,"C");
$display(1,,0,,"C");
$display(5,,0,,"C");
endmodule
`undef MACRO)"},

      {"[** Nested callable macros **]",
       R"(
`define MACRO1(n) real x=n;
`define MACRO2(m) real y=m; `MACRO1(1)
module foo;
`MACRO1(2)
`MACRO2(3)
endmodule
`undef MACRO1
`undef MACRO2)",
       // ...equivalent to
       R"(
`define MACRO1(n) real x=n;
`define MACRO2(m) real y=m; `MACRO1(1)
module foo;
real x=2;
real y=3; real x=1;
endmodule
`undef MACRO1
`undef MACRO2)"}

  };

  for (const auto& test_case : test_cases) {
    PreprocessorTester expanded(
        test_case.pp_input, VerilogPreprocess::Config({.expand_macros = true}));
    EXPECT_TRUE(expanded.Status().ok())
        << expanded.Status() << " " << test_case.description;
    PreprocessorTester equivalent(
        test_case.equivalent,
        VerilogPreprocess::Config({.expand_macros = false}));
    EXPECT_TRUE(equivalent.Status().ok())
        << equivalent.Status() << " " << test_case.description;
    const auto& expanded_stream = expanded.Data().GetTokenStreamView();
    const auto& equivalent_stream = equivalent.Data().GetTokenStreamView();
    EXPECT_GT(expanded_stream.size(), 0) << test_case.description;
    EXPECT_EQ(expanded_stream.size(), equivalent_stream.size())
        << test_case.description;
    auto expanded_it = expanded_stream.begin();
    auto equivalent_it = equivalent_stream.begin();
    while (expanded_it != expanded_stream.end() &&
           equivalent_it != equivalent_stream.end()) {
      EXPECT_EQ((*expanded_it)->text(), (*equivalent_it)->text())
          << test_case.description;
      EXPECT_EQ((*expanded_it)->token_enum(), (*equivalent_it)->token_enum())
          << test_case.description;
      ++expanded_it;
      ++equivalent_it;
    }
  }
}

// TODO(karimtera): This test doesn't use "PreprocessorTester",
// as there isn't a way to tell "VerilogAnalyzer" about external preprocessing
// info. Typically, all tests should use "PreprocessorTester".
TEST(VerilogPreprocessTest, SetExternalDefines) {
  // Test case input tokens.
  const verible::TokenSequence test_case_tokens = {
      {verible::TokenInfo(MacroIdentifier, "`MACRO1")},
      {MacroIdentifier, "`MACRO2"}};
  verible::TokenStreamView test_case_stream_view;
  verible::InitTokenStreamView(test_case_tokens, &test_case_stream_view);

  VerilogPreprocess::Config test_config({.expand_macros = true});
  VerilogPreprocess preprocessor(test_config);

  verilog::TextMacroDefinition macro1("MACRO1", "VALUE1");
  verilog::TextMacroDefinition macro2("MACRO2", "VALUE2");
  verilog::FileList::PreprocessingInfo preprocessing_info;
  preprocessing_info.defines.push_back(macro1);
  preprocessing_info.defines.push_back(macro2);

  preprocessor.setPreprocessingInfo(preprocessing_info);

  const auto& pp_data = preprocessor.ScanStream(test_case_stream_view);

  EXPECT_THAT(pp_data.preprocessed_token_stream[0]->text(), "VALUE1");
  EXPECT_THAT(pp_data.preprocessed_token_stream[1]->text(), "VALUE2");
}

// TODO(karimtera): This test doesn't use "PreprocessorTester",
// as there isn't a way to tell "VerilogAnalyzer" about external preprocessing
// info. Typically, all tests should use "PreprocessorTester".
TEST(VerilogPreprocessTest, ExternalDefinesWithUndef) {
  // Test case input tokens.
  const verible::TokenSequence test_case_tokens = {
      {verible::TokenInfo(PP_undef, "`undef")},
      {verible::TokenInfo(PP_Identifier, "MACRO1")},
      {verible::TokenInfo(MacroIdentifier, "`MACRO1")},
      {verible::TokenInfo(MacroIdentifier, "`MACRO2")}};
  verible::TokenStreamView test_case_stream_view;
  verible::InitTokenStreamView(test_case_tokens, &test_case_stream_view);

  VerilogPreprocess::Config test_config({.expand_macros = true});
  VerilogPreprocess preprocessor(test_config);

  verilog::TextMacroDefinition macro1("MACRO1", "VALUE1");
  verilog::TextMacroDefinition macro2("MACRO2", "VALUE2");
  verilog::FileList::PreprocessingInfo preprocessing_info;
  preprocessing_info.defines.push_back(macro1);
  preprocessing_info.defines.push_back(macro2);

  preprocessor.setPreprocessingInfo(preprocessing_info);

  const auto& pp_data = preprocessor.ScanStream(test_case_stream_view);

  const auto& errors = pp_data.errors;

  EXPECT_THAT(errors.size(), 1);
  EXPECT_THAT(errors.front().error_message,
              StartsWith("Error expanding macro identifier"));
}

TEST(VerilogPreprocessTest, IncludingFileWithAbsolutePath) {
  const auto tempdir = testing::TempDir();
  const std::string includes_dir = JoinPath(tempdir, "includes");
  constexpr absl::string_view included_content(
      "module included_file(); endmodule");
  const absl::string_view included_filename = "included_file.sv";
  const std::string included_absolute_path =
      JoinPath(includes_dir, included_filename);

  const std::string src_content = absl::StrCat(
      "`include \"", included_absolute_path, "\"\nmodule src(); endmodule\n");
  const std::string equivalent_content =
      "module included_file(); endmodule\nmodule src(); endmodule\n";

  FileOpener file_opener =
      [included_absolute_path, included_content](
          absl::string_view filename) -> absl::StatusOr<absl::string_view> {
    if (filename == included_absolute_path) return included_content;
    return absl::NotFoundError(absl::StrCat(filename, " is not found"));
  };
  VerilogPreprocess tester(VerilogPreprocess::Config({.include_files = true}),
                           file_opener);
  VerilogPreprocess equivalent(
      VerilogPreprocess::Config({.include_files = true}));

  LexerTester src_lexer(src_content);
  LexerTester equivalent_lexer(equivalent_content);
  const auto& tester_pp_data =
      tester.ScanStream(src_lexer.GetTokenStreamView());
  const auto& equivalent_pp_data =
      equivalent.ScanStream(equivalent_lexer.GetTokenStreamView());

  EXPECT_TRUE(tester_pp_data.errors.empty());
  EXPECT_TRUE(equivalent_pp_data.errors.empty());

  const auto& tester_stream = tester_pp_data.preprocessed_token_stream;
  const auto& equivalent_stream = equivalent_pp_data.preprocessed_token_stream;
  EXPECT_FALSE(tester_stream.empty());
  EXPECT_EQ(tester_stream.size(), equivalent_stream.size());

  auto tester_it = tester_stream.begin();
  auto equivalent_it = equivalent_stream.begin();
  while (tester_it != tester_stream.end() &&
         equivalent_it != equivalent_stream.end()) {
    EXPECT_EQ((*tester_it)->text(), (*equivalent_it)->text());
    EXPECT_EQ((*tester_it)->token_enum(), (*equivalent_it)->token_enum());
    ++tester_it;
    ++equivalent_it;
  }
}

TEST(VerilogPreprocessTest, IncludingFileWithRelativePath) {
  const auto tempdir = testing::TempDir();
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  constexpr absl::string_view included_content(
      "module included_file(); endmodule");
  const absl::string_view included_filename = "included_file.sv";
  const std::string included_absolute_path =
      JoinPath(includes_dir, included_filename);
  const ScopedTestFile tf(includes_dir, included_content, included_filename);

  const std::string src_content = absl::StrCat("`include \"", included_filename,
                                               "\"\nmodule src(); endmodule\n");
  const std::string equivalent_content =
      "module included_file(); endmodule\nmodule src(); endmodule\n";

  // TODO(karimtera): allow including files with absolute paths.
  // This is a hacky solution for now.
  verilog::VerilogProject project(".", {"/", includes_dir});
  FileOpener file_opener =
      [&project](
          absl::string_view filename) -> absl::StatusOr<absl::string_view> {
    auto result = project.OpenIncludedFile(filename);
    if (!result.status().ok()) return result.status();
    return (*result)->GetContent();
  };
  VerilogPreprocess tester(VerilogPreprocess::Config({.include_files = true}),
                           file_opener);
  VerilogPreprocess equivalent(
      VerilogPreprocess::Config({.include_files = true}));

  LexerTester src_lexer(src_content);
  LexerTester equivalent_lexer(equivalent_content);
  const auto& tester_pp_data =
      tester.ScanStream(src_lexer.GetTokenStreamView());
  const auto& equivalent_pp_data =
      equivalent.ScanStream(equivalent_lexer.GetTokenStreamView());

  EXPECT_TRUE(tester_pp_data.errors.empty());
  EXPECT_TRUE(equivalent_pp_data.errors.empty());

  const auto& tester_stream = tester_pp_data.preprocessed_token_stream;
  const auto& equivalent_stream = equivalent_pp_data.preprocessed_token_stream;
  EXPECT_FALSE(tester_stream.empty());
  EXPECT_EQ(tester_stream.size(), equivalent_stream.size());

  auto tester_it = tester_stream.begin();
  auto equivalent_it = equivalent_stream.begin();
  while (tester_it != tester_stream.end() &&
         equivalent_it != equivalent_stream.end()) {
    EXPECT_EQ((*tester_it)->text(), (*equivalent_it)->text());
    EXPECT_EQ((*tester_it)->token_enum(), (*equivalent_it)->token_enum());
    ++tester_it;
    ++equivalent_it;
  }
}

TEST(VerilogPreprocessTest,
     IncludingFileWithRelativePathWithoutPreprocessingInfo) {
  const auto tempdir = testing::TempDir();
  const std::string includes_dir = JoinPath(tempdir, "includes");
  EXPECT_TRUE(CreateDir(includes_dir).ok());
  constexpr absl::string_view included_content(
      "module included_file(); endmodule\n");
  const absl::string_view included_filename = "included_file.sv";
  const std::string included_absolute_path =
      JoinPath(includes_dir, included_filename);
  const ScopedTestFile tf(includes_dir, included_content, included_filename);
  const std::string src_content = absl::StrCat("`include \"", included_filename,
                                               "\"\nmodule src(); endmodule\n");

  // TODO(karimtera): allow including files with absolute paths.
  // This is a hacky solution for now.
  verilog::VerilogProject project(".", {"/"});
  FileOpener file_opener =
      [&project](
          absl::string_view filename) -> absl::StatusOr<absl::string_view> {
    auto result = project.OpenIncludedFile(filename);
    if (!result.status().ok()) return result.status();
    return (*result)->GetContent();
  };
  VerilogPreprocess tester(VerilogPreprocess::Config({.include_files = true}),
                           file_opener);

  LexerTester src_lexer(src_content);
  const auto& tester_pp_data =
      tester.ScanStream(src_lexer.GetTokenStreamView());

  EXPECT_EQ(tester_pp_data.errors.size(), 1);
  const auto& error = tester_pp_data.errors.front();
  EXPECT_THAT(error.error_message, StartsWith("Unable to find"));
}

}  // namespace
}  // namespace verilog
