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

#include <memory>
#include <vector>

#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/token_info.h"
#include "common/text/tree_builder_test_util.h"
#include "gtest/gtest.h"

namespace verible {
namespace matcher {
namespace {

TEST(DescentPathTest, GetDescendantsFromPathNullTreeFail) {
  SymbolPtr embedded_null = TNode(1, nullptr, TNode(2, nullptr));
  DescentPath path = {NodeTag(2), NodeTag(3), NodeTag(4), LeafTag(100)};

  auto descendants = GetAllDescendantsFromPath(*embedded_null, path);
  EXPECT_EQ(descendants.size(), 0);
}

TEST(DescentPathTest, GetDescendantsFromPathEmbeddedNullPass) {
  SymbolPtr root = TNode(
      1, nullptr, TNode(2), nullptr, TNode(2, nullptr, XLeaf(10)), nullptr,
      TNode(2, nullptr, XLeaf(10), nullptr, TNode(100, nullptr)));
  DescentPath path = {NodeTag(2), LeafTag(10)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 2);

  const auto* leaf1 = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
  const auto* leaf2 = down_cast<const SyntaxTreeLeaf*>(descendants[1]);

  ASSERT_NE(leaf1, nullptr);
  ASSERT_NE(leaf2, nullptr);
  EXPECT_EQ(leaf1->get().token_enum(), 10);
  EXPECT_EQ(leaf2->get().token_enum(), 10);
}

TEST(DescentPathTest, GetDescendantsFromPathSingle) {
  SymbolPtr root = TNode(1, XLeaf(2), nullptr, TNode(2, XLeaf(10)));
  DescentPath path = {NodeTag(2), LeafTag(10)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 1);

  const auto* leaf = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
  ASSERT_NE(leaf, nullptr);
  EXPECT_EQ(leaf->get().token_enum(), 10);
}

TEST(DescentPathTest, GetDescendantsFromPathMultiple) {
  SymbolPtr root = TNode(1, TNode(2, TNode(100), TNode(100)));
  DescentPath path = {NodeTag(2), NodeTag(100)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 2);

  const auto* node1 = down_cast<const SyntaxTreeNode*>(descendants[0]);
  const auto* node2 = down_cast<const SyntaxTreeNode*>(descendants[1]);

  ASSERT_NE(node1, nullptr);
  ASSERT_NE(node2, nullptr);
  EXPECT_TRUE(node1->MatchesTag(100));
  EXPECT_TRUE(node2->MatchesTag(100));
}

TEST(DescentPathTest, GetDescendantsFromPathMultiplePaths) {
  SymbolPtr root =
      TNode(1, TNode(2), TNode(2, XLeaf(10)), TNode(2, XLeaf(10), TNode(100)));
  DescentPath path = {NodeTag(2), LeafTag(10)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 2);

  const auto* leaf1 = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
  const auto* leaf2 = down_cast<const SyntaxTreeLeaf*>(descendants[1]);

  ASSERT_NE(leaf1, nullptr);
  ASSERT_NE(leaf2, nullptr);
  EXPECT_EQ(leaf1->get().token_enum(), 10);
  EXPECT_EQ(leaf2->get().token_enum(), 10);
}

TEST(DescentPathTest, GetDescendantsFromPathFailureGapInPath) {
  SymbolPtr root = TNode(1, TNode(2, TNode(3, XLeaf(100))));
  DescentPath path = {NodeTag(2), LeafTag(100)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 0);
}

TEST(DescentPathTest, GetDescendantsFromPathFailurePathTooLong) {
  SymbolPtr root = TNode(1, TNode(2, TNode(3, XLeaf(100))));
  DescentPath path = {NodeTag(2), NodeTag(3), NodeTag(4), LeafTag(100)};
  auto descendants = GetAllDescendantsFromPath(*root, path);
  EXPECT_EQ(descendants.size(), 0);
}

}  // namespace
}  // namespace matcher
}  // namespace verible
