// Copyright 2017-2022 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/flow_tree.h"

#include <vector>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "common/text/token_stream_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "verilog/parser/verilog_lexer.h"

namespace verilog {
namespace {

using testing::StartsWith;

// Lexes a SystemVerilog source code, and returns a TokenSequence.
verible::TokenSequence LexToSequence(absl::string_view source_contents) {
  verible::TokenSequence lexed_sequence;
  VerilogLexer lexer(source_contents);
  for (lexer.DoNextToken(); !lexer.GetLastToken().isEOF();
       lexer.DoNextToken()) {
    if (verilog::VerilogLexer::KeepSyntaxTreeTokens(lexer.GetLastToken())) {
      lexed_sequence.push_back(lexer.GetLastToken());
    }
  }
  return lexed_sequence;
}

TEST(FlowTree, MultipleConditionalsSameMacro) {
  const absl::string_view test_case =
      R"(
    `ifdef A
      A_TRUE_1
    `else
      A_FALSE_1
    `endif

    `ifdef A
      A_TRUE_2
    `else
      A_FALSE_2
    `endif

    `ifndef A
      A_FALSE_3
    `else
      A_TRUE_3
    `endif)";

  FlowTree tree_test(LexToSequence(test_case));
  std::vector<FlowTree::Variant> variants;
  auto status =
      tree_test.GenerateVariants([&variants](const FlowTree::Variant& variant) {
        variants.push_back(variant);
        return true;
      });
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(variants.size(), 2);

  const auto& used_macros = tree_test.GetUsedMacros();
  EXPECT_EQ(used_macros.size(), 1);
  EXPECT_THAT(used_macros[0]->text(), "A");

  // First variant: A is defined.
  EXPECT_TRUE(variants[0].macros_mask.test(0));
  EXPECT_TRUE(variants[0].visited.test(0));
  EXPECT_THAT(variants[0].sequence[0].text(), "A_TRUE_1");
  EXPECT_THAT(variants[0].sequence[1].text(), "A_TRUE_2");
  EXPECT_THAT(variants[0].sequence[2].text(), "A_TRUE_3");

  // Second variant: A is undefined.
  EXPECT_FALSE(variants[1].macros_mask.test(0));
  EXPECT_TRUE(variants[1].visited.test(0));
  EXPECT_THAT(variants[1].sequence[0].text(), "A_FALSE_1");
  EXPECT_THAT(variants[1].sequence[1].text(), "A_FALSE_2");
  EXPECT_THAT(variants[1].sequence[2].text(), "A_FALSE_3");
}

TEST(FlowTree, UnmatchedElses) {
  const absl::string_view test_cases[] = {
      R"(
    `elsif A
      A_TRUE
    `endif
    )",
      R"(
    `ifdef A
      A_TRUE
    `endif
    `elsif B
      B_TRUE
    `endif
    )",
      R"(
    `else
      A_TRUE
    `endif
    )",
      R"(
    `ifdef A
      `elsif B
        B_TRUE
      `endif
    `endif
    )",
      R"(
    `endif
    )"};

  for (auto test : test_cases) {
    FlowTree tree_test(LexToSequence(test));
    auto status = tree_test.GenerateVariants(
        [](const FlowTree::Variant& variant) { return true; });
    EXPECT_FALSE(status.ok());
    EXPECT_THAT(status.message(), StartsWith("ERROR: Unmatched"));
  }
}

TEST(FlowTree, UnvalidConditionals) {
  const absl::string_view test_cases[] = {
      R"(
    `ifdef A
      A_TRUE
    `elsif
      A_FALSE
      )",
      R"(
    `ifdef
      A_TRUE
    `else
      A_FALSE
      )",
      R"(
    `ifndef
      A_TRUE
    `else
      A_FALSE
    `endif
    )"};

  for (auto test : test_cases) {
    FlowTree tree_test(LexToSequence(test));
    auto status = tree_test.GenerateVariants(
        [](const FlowTree::Variant& variant) { return true; });
    EXPECT_FALSE(status.ok());
  }
}

TEST(FlowTree, UncompletedConditionals) {
  const absl::string_view test_cases[] = {
      R"(
    `ifdef A
      A_TRUE
    `else
      A_FALSE
      )",
      R"(
    `ifdef A
      A_TRUE
      `ifndef B
        B_FALSE
      `else
        B_TRUE
      `endif
    )"};

  for (auto test : test_cases) {
    FlowTree tree_test(LexToSequence(test));
    auto status = tree_test.GenerateVariants(
        [](const FlowTree::Variant& variant) { return true; });
    EXPECT_FALSE(status.ok());
    EXPECT_THAT(status.message(), StartsWith("ERROR: Uncompleted"));
  }
}

TEST(FlowTree, NestedConditionals) {
  const absl::string_view test_cases[] = {
      R"(
    `ifdef A
      `ifdef B
        A_B
      `else
        A_nB
      `endif
    `else
      nA_B_or_nA_nB
    `endif)"};

  for (auto test : test_cases) {
    FlowTree tree_test(LexToSequence(test));
    std::vector<FlowTree::Variant> variants;
    auto status = tree_test.GenerateVariants(
        [&variants](const FlowTree::Variant& variant) {
          variants.push_back(variant);
          return true;
        });
    EXPECT_TRUE(status.ok());
    EXPECT_EQ(variants.size(), 3);
    for (const auto& variant : variants) {
      EXPECT_EQ(variant.sequence.size(), 1);
      if (variant.macros_mask.test(0) == 0) {
        // Check that if A is undefined, then B is not visited.
        EXPECT_FALSE(variant.visited.test(1));
      } else {
        // Check that if A is defined, then B is visited.
        EXPECT_TRUE(variant.visited.test(1));
      }
    }
    const auto& used_macros = tree_test.GetUsedMacros();
    EXPECT_EQ(used_macros.size(), 2);
    EXPECT_THAT(used_macros[0]->text(), "A");
    EXPECT_THAT(used_macros[1]->text(), "B");
  }
}

TEST(FlowTree, MultipleElseIfs) {
  const absl::string_view test_case =
      R"(
    `ifdef A
      A_TRUE
    `elsif B
      B_TRUE
    `elsif EMPTY
    `elsif C
      C_TRUE
    `endif)";

  FlowTree tree_test(LexToSequence(test_case));
  std::vector<FlowTree::Variant> variants;
  auto status =
      tree_test.GenerateVariants([&variants](const FlowTree::Variant& variant) {
        variants.push_back(variant);
        return true;
      });
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(variants.size(), 5);

  const auto& used_macros = tree_test.GetUsedMacros();
  EXPECT_EQ(used_macros.size(), 4);
  EXPECT_THAT(used_macros[0]->text(), "A");
  EXPECT_THAT(used_macros[1]->text(), "B");
  EXPECT_THAT(used_macros[2]->text(), "EMPTY");
  EXPECT_THAT(used_macros[3]->text(), "C");

  // A is defined.
  EXPECT_TRUE(variants[0].macros_mask.test(0));
  EXPECT_THAT(variants[0].sequence[0].text(), "A_TRUE");

  // B is defined.
  EXPECT_TRUE(variants[1].macros_mask.test(1));
  EXPECT_THAT(variants[1].sequence[0].text(), "B_TRUE");

  // EMPTY is defined.
  EXPECT_TRUE(variants[2].macros_mask.test(2));
  EXPECT_TRUE(variants[2].sequence.empty());

  // C is defined.
  EXPECT_TRUE(variants[3].macros_mask.test(3));
  EXPECT_THAT(variants[3].sequence[0].text(), "C_TRUE");
}

TEST(FlowTree, SwappedNegatedIfs) {
  const absl::string_view test_case =
      R"(
    `ifndef A
      A_FALSE
    `elsif B
      B_TRUE
    `endif

    `ifndef B
      B_FALSE
    `elsif A
      A_TRUE
    `endif)";

  FlowTree tree_test(LexToSequence(test_case));
  std::vector<FlowTree::Variant> variants;
  auto status =
      tree_test.GenerateVariants([&variants](const FlowTree::Variant& variant) {
        variants.push_back(variant);
        return true;
      });
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(variants.size(), 4);

  const auto& used_macros = tree_test.GetUsedMacros();
  EXPECT_EQ(used_macros.size(), 2);
  EXPECT_THAT(used_macros[0]->text(), "A");
  EXPECT_THAT(used_macros[1]->text(), "B");

  EXPECT_THAT(variants[0].sequence[0].text(), "A_FALSE");
  EXPECT_THAT(variants[0].sequence[1].text(), "B_FALSE");

  EXPECT_THAT(variants[1].sequence[0].text(), "A_FALSE");

  EXPECT_THAT(variants[2].sequence[0].text(), "B_TRUE");
  EXPECT_THAT(variants[2].sequence[1].text(), "A_TRUE");

  EXPECT_THAT(variants[3].sequence[0].text(), "B_FALSE");
}

TEST(FlowTree, CompleteConditional) {
  const absl::string_view test_case =
      R"(
    `ifdef A
      A_TRUE
    `elsif B
      B_TRUE
    `elsif C
      C_TRUE
    `else
      ALL_FALSE
    `endif)";

  FlowTree tree_test(LexToSequence(test_case));
  std::vector<FlowTree::Variant> variants;
  auto status =
      tree_test.GenerateVariants([&variants](const FlowTree::Variant& variant) {
        variants.push_back(variant);
        return true;
      });
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(variants.size(), 4);

  const auto& used_macros = tree_test.GetUsedMacros();
  EXPECT_EQ(used_macros.size(), 3);
  EXPECT_THAT(used_macros[0]->text(), "A");
  EXPECT_THAT(used_macros[1]->text(), "B");
  EXPECT_THAT(used_macros[2]->text(), "C");

  EXPECT_TRUE(variants[0].macros_mask.test(0));
  EXPECT_THAT(variants[0].sequence[0].text(), "A_TRUE");

  EXPECT_TRUE(variants[1].macros_mask.test(1));
  EXPECT_THAT(variants[1].sequence[0].text(), "B_TRUE");

  EXPECT_TRUE(variants[2].macros_mask.test(2));
  EXPECT_THAT(variants[2].sequence[0].text(), "C_TRUE");

  EXPECT_THAT(variants[3].sequence[0].text(), "ALL_FALSE");
}

}  // namespace
}  // namespace verilog
