// 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 "common/analysis/syntax_tree_linter.h"

#include <memory>
#include <vector>

#include "common/analysis/lint_rule_status.h"
#include "common/analysis/syntax_tree_lint_rule.h"
#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/syntax_tree_context.h"
#include "common/text/token_info.h"
#include "common/text/tree_builder_test_util.h"
#include "gtest/gtest.h"

namespace verible {
namespace {

// Simple rule for testing that verifies that all leafs contained in tree
// are tagged as a certain value. This value is passed in via the constructor
class AllLeavesMustBeN : public SyntaxTreeLintRule {
 public:
  // Constructor that takes n, the number that this rule is checking for
  explicit AllLeavesMustBeN(int n) : target_(n) {}

  // When handling leaf, check that it has target tag and report a violation
  // is not
  void HandleLeaf(const SyntaxTreeLeaf& leaf,
                  const SyntaxTreeContext& context) final {
    if (leaf.get().token_enum() != target_) {
      violations_.insert(LintViolation(leaf.get(), "", context));
    }
  }

  // Do not operate on nodes
  void HandleNode(const SyntaxTreeNode& node,
                  const SyntaxTreeContext& context) final {}
  LintRuleStatus Report() const final { return LintRuleStatus(violations_); }

 private:
  std::set<LintViolation> violations_;
  int target_;
};

std::unique_ptr<SyntaxTreeLintRule> MakeRuleN(int n) {
  return std::unique_ptr<SyntaxTreeLintRule>(new AllLeavesMustBeN(n));
}

TEST(SyntaxTreeLinterTest, BasicUsageCorrect) {
  const SymbolPtr root = Node(XLeaf(2), XLeaf(2), Node(XLeaf(2)), XLeaf(2));

  SyntaxTreeLinter linter;
  linter.AddRule(MakeRuleN(2));

  ASSERT_NE(root, nullptr);
  linter.Lint(*root);
  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_TRUE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 0);
}

TEST(SyntaxTreeLinterTest, BasicUsageFailure) {
  SymbolPtr root = Node(XLeaf(2), XLeaf(2), Node(XLeaf(2)), XLeaf(3));

  SyntaxTreeLinter linter;
  linter.AddRule(MakeRuleN(2));

  ASSERT_NE(root, nullptr);
  linter.Lint(*root);
  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_FALSE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 1);
}

TEST(SyntaxTreeLinterTest, MultipleRules) {
  constexpr absl::string_view text("abcd");
  SymbolPtr root =
      Node(Leaf(2, text.substr(0, 1)), Leaf(2, text.substr(1, 1)),
           Node(Leaf(2, text.substr(2, 1))), Leaf(2, text.substr(3, 1)));

  SyntaxTreeLinter linter;
  linter.AddRule(MakeRuleN(2));
  linter.AddRule(MakeRuleN(3));

  ASSERT_NE(root, nullptr);
  linter.Lint(*root);
  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 2);
  EXPECT_TRUE(statuses[0].isOk());
  EXPECT_FALSE(statuses[1].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 0);
  EXPECT_EQ(statuses[1].violations.size(), 4);
}

// Simple testing rule that verifies that every node's leaf children have tags
// that are in ascending order
class ChildrenLeavesAscending : public SyntaxTreeLintRule {
 public:
  // Do not process leaves
  void HandleLeaf(const SyntaxTreeLeaf& leaf,
                  const SyntaxTreeContext& context) final {}

  // When handling nodes, iterate through all children and check that tags
  // are ascending. Report leafs nodes that have leaves that are out of order.
  void HandleNode(const SyntaxTreeNode& node,
                  const SyntaxTreeContext& context) final {
    int last_tag = 0;
    for (const auto& child : node.children()) {
      if (child->Kind() == SymbolKind::kLeaf) {
        const SyntaxTreeLeaf* leaf_child =
            down_cast<SyntaxTreeLeaf*>(child.get());
        const int current_tag = leaf_child->get().token_enum();
        if (current_tag >= last_tag) {
          last_tag = current_tag;
        } else {
          violations_.insert(LintViolation(leaf_child->get(), "", context));
          return;
        }
      }
    }
  }

  LintRuleStatus Report() const final { return LintRuleStatus(violations_); }

 private:
  std::set<LintViolation> violations_;
};

std::unique_ptr<SyntaxTreeLintRule> MakeAscending() {
  return std::unique_ptr<SyntaxTreeLintRule>(new ChildrenLeavesAscending());
}

TEST(SyntaxTreeLinterTest, AscendingSuccess) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(4, text.substr(1, 1)),
           Node(Leaf(2, text.substr(2, 1)), Leaf(10, text.substr(3, 1))),
           Leaf(7, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeAscending());
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_TRUE(statuses[0].isOk());
}

TEST(SyntaxTreeLinterTest, AscendingFailsOnce) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(4, text.substr(1, 1)),
           Node(Leaf(2, text.substr(2, 1)), Leaf(10, text.substr(3, 1))),
           Leaf(1, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeAscending());
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_FALSE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 1);
}

TEST(SyntaxTreeLinterTest, AscendingFailsTwice) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(4, text.substr(1, 1)),
           Node(Leaf(210, text.substr(2, 1)), Leaf(10, text.substr(3, 1))),
           Leaf(1, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeAscending());
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_FALSE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 2);
}

TEST(SyntaxTreeLinterTest, HeterogenousTests) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(4, text.substr(1, 1)),
           Node(Leaf(210, text.substr(2, 1)), Leaf(10, text.substr(3, 1))),
           Leaf(1, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeAscending());
  linter.AddRule(MakeRuleN(1));
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 2);
  EXPECT_FALSE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 2);
  EXPECT_FALSE(statuses[1].isOk());
  EXPECT_EQ(statuses[1].violations.size(), 3);
}

// Simple testing rule that verifies that each leaf's tag is the same as its
// depth in the tree.
class TagMatchesContextDepth : public SyntaxTreeLintRule {
 public:
  // When handling a leaf, check leaf's tag vs the size of its context
  void HandleLeaf(const SyntaxTreeLeaf& leaf,
                  const SyntaxTreeContext& context) final {
    if (static_cast<size_t>(leaf.get().token_enum()) != context.size()) {
      violations_.insert(LintViolation(leaf.get(), "", context));
    }
  }
  // Do not process nodes
  void HandleNode(const SyntaxTreeNode& node,
                  const SyntaxTreeContext& context) final {}

  LintRuleStatus Report() const final { return LintRuleStatus(violations_); }

 private:
  std::set<LintViolation> violations_;
};

std::unique_ptr<SyntaxTreeLintRule> MakeDepth() {
  return std::unique_ptr<SyntaxTreeLintRule>(new TagMatchesContextDepth());
}

TEST(SyntaxTreeLinterTest, DepthFails) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(4, text.substr(1, 1)),
           Node(Leaf(210, text.substr(2, 1)), Leaf(10, text.substr(3, 1))),
           Leaf(1, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeDepth());
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_FALSE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 3);
}

TEST(SyntaxTreeLinterTest, DepthSuccess) {
  constexpr absl::string_view text("abcde");
  SymbolPtr root =
      Node(Leaf(1, text.substr(0, 1)), Leaf(1, text.substr(1, 1)),
           Node(Leaf(2, text.substr(2, 1)), Leaf(2, text.substr(3, 1))),
           Leaf(1, text.substr(4, 1)));
  SyntaxTreeLinter linter;
  linter.AddRule(MakeDepth());
  ASSERT_NE(root.get(), nullptr);
  linter.Lint(*root.get());

  std::vector<LintRuleStatus> statuses = linter.ReportStatus();
  EXPECT_EQ(statuses.size(), 1);
  EXPECT_TRUE(statuses[0].isOk());
  EXPECT_EQ(statuses[0].violations.size(), 0);
}

}  // namespace
}  // namespace verible
