/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * 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 "cobalt/dom/node.h"

#include "base/basictypes.h"
#include "cobalt/dom/comment.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/global_stats.h"
#include "cobalt/dom/html_collection.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/node_list.h"
#include "cobalt/dom/testing/gtest_workarounds.h"
#include "cobalt/dom/text.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace dom {
namespace {

const scoped_refptr<Node> kNullNode;
const scoped_refptr<HTMLCollection> kNullCollection;

// Helper function that validates that the children of the given node are
// identical to the provided expected array.
template <int N>
void ExpectNodeChildrenEq(scoped_refptr<Node>(&children)[N],
                          const scoped_refptr<Node>& node) {
  // Make sure that we have at least one child.
  COMPILE_ASSERT(N >= 1, expect_node_children_has_no_child);

  EXPECT_EQ(children[0], node->first_child());
  EXPECT_EQ(children[N - 1], node->last_child());
  EXPECT_EQ(NULL, children[0]->previous_sibling());
  EXPECT_EQ(NULL, children[N - 1]->next_sibling());

  for (int i = 0; i < N; ++i) {
    EXPECT_EQ(node, children[i]->parent_node());

    if (i > 0) {
      EXPECT_EQ(children[i - 1], children[i]->previous_sibling());
    }

    if (i < N - 1) {
      EXPECT_EQ(children[i + 1], children[i]->next_sibling());
    }
  }
}

}  // namespace

//////////////////////////////////////////////////////////////////////////
// NodeTest
//////////////////////////////////////////////////////////////////////////

class NodeTest : public ::testing::Test {
 protected:
  NodeTest();
  ~NodeTest() OVERRIDE;

  HTMLElementContext html_element_context_;
  scoped_refptr<Document> document_;
};

NodeTest::NodeTest()
    : html_element_context_(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                            NULL, NULL, NULL, NULL, "") {
  EXPECT_TRUE(GlobalStats::GetInstance()->CheckNoLeaks());

  document_ = new Document(&html_element_context_);
}

NodeTest::~NodeTest() {
  document_ = NULL;
  EXPECT_TRUE(GlobalStats::GetInstance()->CheckNoLeaks());
}

//////////////////////////////////////////////////////////////////////////
// Test cases
//////////////////////////////////////////////////////////////////////////

TEST_F(NodeTest, CreateNode) {
  scoped_refptr<Node> node = new Element(document_);
  ASSERT_TRUE(node);
}

TEST_F(NodeTest, CloneNode) {
  scoped_refptr<Element> root = new Element(document_, base::Token("root"));
  root->SetAttribute("id", "root");
  root->AppendChild(new Text(document_, "text"));
  scoped_refptr<Element> child =
      root->AppendChild(new Element(document_, base::Token("child")))
          ->AsElement();
  child->SetAttribute("id", "child");

  // Shallow clone should only clone the node itself.
  scoped_refptr<Node> shallow_clone = root->CloneNode(false);
  ASSERT_TRUE(shallow_clone->IsElement());
  EXPECT_EQ("root", shallow_clone->AsElement()->GetAttribute("id").value());
  EXPECT_FALSE(shallow_clone->HasChildNodes());

  // Deep clone should clone the node and its descendants.
  scoped_refptr<Node> deep_clone = root->CloneNode(true);
  ASSERT_TRUE(deep_clone->IsElement());
  EXPECT_EQ("root", deep_clone->AsElement()->GetAttribute("id").value());
  ASSERT_EQ(2, deep_clone->child_nodes()->length());
  EXPECT_TRUE(deep_clone->first_child()->IsText());
  EXPECT_EQ("text", deep_clone->first_child()->AsText()->data());
  EXPECT_TRUE(deep_clone->last_child()->IsElement());
  EXPECT_EQ("child",
            deep_clone->last_child()->AsElement()->GetAttribute("id").value());
}

TEST_F(NodeTest, AppendChild) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->AppendChild(new Element(document_));
  ASSERT_TRUE(child1);
  scoped_refptr<Node> child2 = root->AppendChild(new Element(document_));
  ASSERT_TRUE(child2);

  // Properly handle NULL input.
  EXPECT_EQ(NULL, root->AppendChild(NULL));

  scoped_refptr<Node> children[] = {child1, child2};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, AppendChildTwice) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->AppendChild(new Element(document_));
  scoped_refptr<Node> child2 = root->AppendChild(new Element(document_));

  // Append child1 for the second time.
  root->AppendChild(child1);

  scoped_refptr<Node> children[] = {child2, child1};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, Contains) {
  scoped_refptr<Node> root = new Element(document_);
  scoped_refptr<Node> node = new Element(document_);

  scoped_refptr<Node> child1 = root->AppendChild(new Element(document_));
  scoped_refptr<Node> child2 = root->AppendChild(new Element(document_));

  EXPECT_TRUE(root->Contains(child1));
  EXPECT_TRUE(root->Contains(child2));

  EXPECT_FALSE(root->Contains(root));
  EXPECT_FALSE(root->Contains(node));
}

TEST_F(NodeTest, AppendChildWithParent) {
  scoped_refptr<Node> root1 = new Element(document_);
  scoped_refptr<Node> root2 = new Element(document_);

  scoped_refptr<Node> child = new Element(document_);
  root1->AppendChild(child);
  root2->AppendChild(child);

  EXPECT_FALSE(root1->Contains(child));
  EXPECT_TRUE(root2->Contains(child));

  EXPECT_EQ(root2, child->parent_node());
}

TEST_F(NodeTest, InsertBefore) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->InsertBefore(new Element(document_), NULL);
  ASSERT_TRUE(child1);
  scoped_refptr<Node> child3 = root->InsertBefore(new Element(document_), NULL);
  ASSERT_TRUE(child3);
  scoped_refptr<Node> child2 =
      root->InsertBefore(new Element(document_), child3);
  ASSERT_TRUE(child2);

  // Properly handle NULL input.
  EXPECT_EQ(NULL, root->InsertBefore(NULL, NULL));
  // Properly handle a reference node that is not a child of root.
  EXPECT_EQ(NULL,
            root->InsertBefore(new Element(document_), new Element(document_)));

  scoped_refptr<Node> children[] = {child1, child2, child3};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, InsertBeforeTwice) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->InsertBefore(new Element(document_), NULL);
  scoped_refptr<Node> child2 = root->InsertBefore(new Element(document_), NULL);

  EXPECT_TRUE(root->InsertBefore(child2, child1));

  scoped_refptr<Node> children[] = {child2, child1};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, InsertBeforeSelf) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->InsertBefore(new Element(document_), NULL);
  scoped_refptr<Node> child2 = root->InsertBefore(new Element(document_), NULL);

  EXPECT_TRUE(root->InsertBefore(child2, child2));

  scoped_refptr<Node> children[] = {child1, child2};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, InsertIntoAnotherDocument) {
  scoped_refptr<Node> root = new Element(document_);
  EXPECT_EQ(document_, root->node_document());

  scoped_refptr<Document> new_document = new Document(&html_element_context_);
  new_document->AppendChild(root);
  EXPECT_EQ(new_document, root->node_document());
}

TEST_F(NodeTest, RemoveChild) {
  scoped_refptr<Node> root = new Element(document_);

  scoped_refptr<Node> child1 = root->AppendChild(new Element(document_));
  scoped_refptr<Node> child2 = root->AppendChild(new Element(document_));
  scoped_refptr<Node> child3 = root->AppendChild(new Element(document_));

  EXPECT_TRUE(root->RemoveChild(child1));
  EXPECT_TRUE(root->RemoveChild(child3));

  // Properly handle NULL input.
  EXPECT_EQ(NULL, root->RemoveChild(NULL));
  // Properly handle a node that is not a child of root.
  EXPECT_EQ(NULL, root->RemoveChild(child1));

  scoped_refptr<Node> children[] = {child2};
  ExpectNodeChildrenEq(children, root);
}

TEST_F(NodeTest, ChildNodes) {
  scoped_refptr<Node> root = new Element(document_);
  EXPECT_FALSE(root->HasChildNodes());
  EXPECT_EQ(0, root->child_nodes()->length());
  EXPECT_EQ(kNullNode, root->child_nodes()->Item(0));

  scoped_refptr<Node> child = new Element(document_);
  root->AppendChild(child);
  EXPECT_TRUE(root->HasChildNodes());
  EXPECT_EQ(1, root->child_nodes()->length());
  EXPECT_EQ(child, root->child_nodes()->Item(0));
  EXPECT_EQ(kNullNode, root->child_nodes()->Item(1));

  root->RemoveChild(child);
  EXPECT_FALSE(root->HasChildNodes());
  EXPECT_EQ(0, root->child_nodes()->length());
  EXPECT_EQ(kNullNode, root->child_nodes()->Item(0));
}

TEST_F(NodeTest, ParentElement) {
  scoped_refptr<Node> root = new Element(document_);
  EXPECT_EQ(NULL, root->parent_element());

  document_->AppendChild(root);
  EXPECT_EQ(NULL, root->parent_element());

  scoped_refptr<Node> child = new Element(document_);
  root->AppendChild(child);
  EXPECT_EQ(root, child->parent_element());

  root->RemoveChild(child);
  EXPECT_EQ(NULL, child->parent_element());
}

TEST_F(NodeTest, ParentNode) {
  scoped_refptr<Node> node = new Element(document_);
  node->AppendChild(new Text(document_, "first"));
  scoped_refptr<Element> child1 =
      node->AppendChild(new Element(document_, base::Token("child1")))
          ->AsElement();
  node->AppendChild(new Text(document_, "middle"));
  scoped_refptr<Element> child2 =
      node->AppendChild(new Element(document_, base::Token("child2")))
          ->AsElement();
  node->AppendChild(new Text(document_, "last"));
  child1->SetAttribute("id", "1");
  child2->SetAttribute("id", "2");
  scoped_refptr<HTMLCollection> children = node->children();

  // Check the result of the methods on ParentNode.
  EXPECT_EQ(2, node->child_element_count());
  EXPECT_EQ(child1, node->first_element_child());
  EXPECT_EQ(child2, node->last_element_child());
  ASSERT_TRUE(children);
  EXPECT_EQ(2, children->length());
  EXPECT_EQ(child1, children->Item(0));
  EXPECT_EQ(child2, children->Item(1));
  EXPECT_EQ(kNullNode, children->Item(2));
  EXPECT_EQ(child1, children->NamedItem("1"));
  EXPECT_EQ(child2, children->NamedItem("2"));
  EXPECT_EQ(kNullNode, children->NamedItem("3"));

  // Remove a child and make sure that the children collection was updated
  // accordingly.
  node->RemoveChild(child2);
  EXPECT_EQ(1, children->length());
  EXPECT_EQ(child1, children->Item(0));
  EXPECT_EQ(kNullNode, children->Item(1));
  EXPECT_EQ(child1, children->NamedItem("1"));
  EXPECT_EQ(kNullNode, children->NamedItem("2"));
}

TEST_F(NodeTest, NonDocumentTypeChildNode) {
  scoped_refptr<Node> node = new Element(document_);
  node->AppendChild(new Text(document_, "first"));
  scoped_refptr<Element> child1 =
      node->AppendChild(new Element(document_, base::Token("child1")))
          ->AsElement();
  node->AppendChild(new Text(document_, "middle"));
  scoped_refptr<Element> child2 =
      node->AppendChild(new Element(document_, base::Token("child2")))
          ->AsElement();
  scoped_refptr<Element> child3 =
      node->AppendChild(new Element(document_, base::Token("child3")))
          ->AsElement();
  node->AppendChild(new Text(document_, "last"));
  scoped_refptr<HTMLCollection> children = node->children();

  EXPECT_EQ(kNullNode, child1->previous_element_sibling());
  EXPECT_EQ(child1, child2->previous_element_sibling());
  EXPECT_EQ(child2, child3->previous_element_sibling());
  EXPECT_EQ(child2, child1->next_element_sibling());
  EXPECT_EQ(child3, child2->next_element_sibling());
  EXPECT_EQ(kNullNode, child3->next_element_sibling());
}

TEST_F(NodeTest, OwnerDocumentAndNodeDocument) {
  scoped_refptr<Node> element1 = new Element(document_);
  scoped_refptr<Node> element2 = new Element(document_);
  EXPECT_FALSE(document_->owner_document());
  EXPECT_EQ(document_, document_->node_document());
  EXPECT_EQ(document_, element1->owner_document());
  EXPECT_EQ(document_, element1->node_document());
  EXPECT_EQ(document_, element2->owner_document());
  EXPECT_EQ(document_, element2->node_document());
}

TEST_F(NodeTest, AdoptIntoDocument) {
  scoped_refptr<Element> element = new Element(document_);
  document_->AppendChild(element);
  EXPECT_EQ(document_, element->node_document());

  scoped_refptr<Document> new_document = new Document(&html_element_context_);
  element->AdoptIntoDocument(new_document);
  EXPECT_EQ(new_document, element->node_document());
  EXPECT_EQ(NULL, element->parent_node());
}

}  // namespace dom
}  // namespace cobalt
