// 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 <set>
#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
