// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"

#include <memory>
#include <vector>

#include "testing/gtest/include/gtest/gtest.h"

class CXFA_NodeIteratorTemplateTest : public testing::Test {
 public:
  class Node {
   public:
    class Strategy {
     public:
      static Node* GetFirstChild(Node* pNode) {
        return pNode && !pNode->children_.empty() ? pNode->children_.front()
                                                  : nullptr;
      }
      static Node* GetNextSibling(Node* pNode) {
        return pNode ? pNode->next_sibling_ : nullptr;
      }
      static Node* GetParent(Node* pNode) {
        return pNode ? pNode->parent_ : nullptr;
      }
    };

    explicit Node(Node* parent) : parent_(parent) {
      if (parent) {
        if (!parent->children_.empty())
          parent->children_.back()->next_sibling_ = this;
        parent->children_.push_back(this);
      }
    }

   private:
    Node* const parent_;
    Node* next_sibling_ = nullptr;
    std::vector<Node*> children_;
  };

  using Iterator = CXFA_NodeIteratorTemplate<Node, Node::Strategy>;

  // Builds a tree along the lines of:
  //
  //   root
  //   |
  //   child1--child2
  //            |
  //            child3------------child7--child9
  //            |                 |
  //            child4--child6    child8
  //            |
  //            child5
  //
  void SetUp() override {
    root_ = std::make_unique<Node>(nullptr);
    child1_ = std::make_unique<Node>(root_.get());
    child2_ = std::make_unique<Node>(root_.get());
    child3_ = std::make_unique<Node>(child2_.get());
    child4_ = std::make_unique<Node>(child3_.get());
    child5_ = std::make_unique<Node>(child4_.get());
    child6_ = std::make_unique<Node>(child3_.get());
    child7_ = std::make_unique<Node>(child2_.get());
    child8_ = std::make_unique<Node>(child7_.get());
    child9_ = std::make_unique<Node>(child2_.get());
  }

  Node* root() const { return root_.get(); }
  Node* child1() const { return child1_.get(); }
  Node* child2() const { return child2_.get(); }
  Node* child3() const { return child3_.get(); }
  Node* child4() const { return child4_.get(); }
  Node* child5() const { return child5_.get(); }
  Node* child6() const { return child6_.get(); }
  Node* child7() const { return child7_.get(); }
  Node* child8() const { return child8_.get(); }
  Node* child9() const { return child9_.get(); }

 protected:
  std::unique_ptr<Node> root_;
  std::unique_ptr<Node> child1_;
  std::unique_ptr<Node> child2_;
  std::unique_ptr<Node> child3_;
  std::unique_ptr<Node> child4_;
  std::unique_ptr<Node> child5_;
  std::unique_ptr<Node> child6_;
  std::unique_ptr<Node> child7_;
  std::unique_ptr<Node> child8_;
  std::unique_ptr<Node> child9_;
};

TEST_F(CXFA_NodeIteratorTemplateTest, Empty) {
  Iterator iter(nullptr);
  EXPECT_EQ(nullptr, iter.GetRoot());
  EXPECT_EQ(nullptr, iter.GetCurrent());
  EXPECT_EQ(nullptr, iter.MoveToNext());
  EXPECT_EQ(nullptr, iter.MoveToPrev());
  EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
}

TEST_F(CXFA_NodeIteratorTemplateTest, Root) {
  Iterator iter(root());
  EXPECT_EQ(root(), iter.GetRoot());
  EXPECT_EQ(root(), iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, Current) {
  Iterator iter(root());
  iter.SetCurrent(child1());
  EXPECT_EQ(root(), iter.GetRoot());
  EXPECT_EQ(child1(), iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, CurrentOutsideRootDisallowed) {
  Iterator iter(child1());
  iter.SetCurrent(root());
  EXPECT_EQ(child1(), iter.GetRoot());
  EXPECT_EQ(nullptr, iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, CurrentNull) {
  Iterator iter(root());
  EXPECT_EQ(child1(), iter.MoveToNext());

  iter.SetCurrent(nullptr);
  EXPECT_EQ(nullptr, iter.GetCurrent());

  EXPECT_EQ(nullptr, iter.MoveToNext());
  EXPECT_EQ(nullptr, iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, MoveToPrev) {
  Iterator iter(root());
  iter.SetCurrent(child9());

  EXPECT_EQ(child8(), iter.MoveToPrev());
  EXPECT_EQ(child8(), iter.GetCurrent());

  EXPECT_EQ(child7(), iter.MoveToPrev());
  EXPECT_EQ(child7(), iter.GetCurrent());

  EXPECT_EQ(child6(), iter.MoveToPrev());
  EXPECT_EQ(child6(), iter.GetCurrent());

  EXPECT_EQ(child5(), iter.MoveToPrev());
  EXPECT_EQ(child5(), iter.GetCurrent());

  EXPECT_EQ(child4(), iter.MoveToPrev());
  EXPECT_EQ(child4(), iter.GetCurrent());

  EXPECT_EQ(child3(), iter.MoveToPrev());
  EXPECT_EQ(child3(), iter.GetCurrent());

  EXPECT_EQ(child2(), iter.MoveToPrev());
  EXPECT_EQ(child2(), iter.GetCurrent());

  EXPECT_EQ(child1(), iter.MoveToPrev());
  EXPECT_EQ(child1(), iter.GetCurrent());

  EXPECT_EQ(root(), iter.MoveToPrev());
  EXPECT_EQ(root(), iter.GetCurrent());

  EXPECT_EQ(nullptr, iter.MoveToPrev());
  EXPECT_EQ(root(), iter.GetCurrent());

  EXPECT_EQ(nullptr, iter.MoveToPrev());
  EXPECT_EQ(root(), iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, MoveToNext) {
  Iterator iter(root());
  iter.SetCurrent(child2());

  EXPECT_EQ(child3(), iter.MoveToNext());
  EXPECT_EQ(child3(), iter.GetCurrent());

  EXPECT_EQ(child4(), iter.MoveToNext());
  EXPECT_EQ(child4(), iter.GetCurrent());

  EXPECT_EQ(child5(), iter.MoveToNext());
  EXPECT_EQ(child5(), iter.GetCurrent());

  EXPECT_EQ(child6(), iter.MoveToNext());
  EXPECT_EQ(child6(), iter.GetCurrent());

  EXPECT_EQ(child7(), iter.MoveToNext());
  EXPECT_EQ(child7(), iter.GetCurrent());

  EXPECT_EQ(child8(), iter.MoveToNext());
  EXPECT_EQ(child8(), iter.GetCurrent());

  EXPECT_EQ(child9(), iter.MoveToNext());
  EXPECT_EQ(child9(), iter.GetCurrent());

  EXPECT_EQ(nullptr, iter.MoveToNext());
  EXPECT_EQ(nullptr, iter.GetCurrent());

  EXPECT_EQ(nullptr, iter.MoveToNext());
  EXPECT_EQ(nullptr, iter.GetCurrent());
}

TEST_F(CXFA_NodeIteratorTemplateTest, SkipChildrenAndMoveToNext) {
  Iterator iter(root());
  iter.SetCurrent(child3());
  EXPECT_EQ(child7(), iter.SkipChildrenAndMoveToNext());
  EXPECT_EQ(child9(), iter.SkipChildrenAndMoveToNext());
  EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
}

TEST_F(CXFA_NodeIteratorTemplateTest, BackAndForth) {
  Iterator iter(root());
  EXPECT_EQ(child1(), iter.MoveToNext());
  EXPECT_EQ(child2(), iter.MoveToNext());
  EXPECT_EQ(child3(), iter.MoveToNext());
  EXPECT_EQ(child4(), iter.MoveToNext());
  EXPECT_EQ(child5(), iter.MoveToNext());
  EXPECT_EQ(child4(), iter.MoveToPrev());
  EXPECT_EQ(child3(), iter.MoveToPrev());
  EXPECT_EQ(child2(), iter.MoveToPrev());
  EXPECT_EQ(child1(), iter.MoveToPrev());
}

TEST_F(CXFA_NodeIteratorTemplateTest, NextFromBeforeTheBeginning) {
  Iterator iter(root());
  EXPECT_EQ(nullptr, iter.MoveToPrev());
  EXPECT_EQ(root(), iter.GetCurrent());
  EXPECT_EQ(child1(), iter.MoveToNext());
}

TEST_F(CXFA_NodeIteratorTemplateTest, PrevFromAfterTheEnd) {
  Iterator iter(root());
  iter.SetCurrent(child9());
  EXPECT_EQ(nullptr, iter.MoveToNext());
  EXPECT_EQ(child9(), iter.MoveToPrev());
}

TEST_F(CXFA_NodeIteratorTemplateTest, ChildAsRootPrev) {
  Iterator iter(child3());
  EXPECT_EQ(nullptr, iter.MoveToPrev());

  iter.SetCurrent(child4());
  EXPECT_EQ(child3(), iter.MoveToPrev());
  EXPECT_EQ(nullptr, iter.MoveToPrev());
}

TEST_F(CXFA_NodeIteratorTemplateTest, ChildAsRootNext) {
  Iterator iter(child3());
  iter.SetCurrent(child4());
  EXPECT_EQ(child5(), iter.MoveToNext());
  EXPECT_EQ(child6(), iter.MoveToNext());
  EXPECT_EQ(nullptr, iter.MoveToNext());
}
