// 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"
#include "third_party/base/ptr_util.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), next_sibling_(nullptr) {
      if (parent) {
        if (!parent->children_.empty())
          parent->children_.back()->next_sibling_ = this;
        parent->children_.push_back(this);
      }
    }

   private:
    Node* parent_;
    Node* next_sibling_;
    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_ = pdfium::MakeUnique<Node>(nullptr);
    child1_ = pdfium::MakeUnique<Node>(root_.get());
    child2_ = pdfium::MakeUnique<Node>(root_.get());
    child3_ = pdfium::MakeUnique<Node>(child2_.get());
    child4_ = pdfium::MakeUnique<Node>(child3_.get());
    child5_ = pdfium::MakeUnique<Node>(child4_.get());
    child6_ = pdfium::MakeUnique<Node>(child3_.get());
    child7_ = pdfium::MakeUnique<Node>(child2_.get());
    child8_ = pdfium::MakeUnique<Node>(child7_.get());
    child9_ = pdfium::MakeUnique<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());
}
