// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is a copy of Chromium's /src/base/containers/linked_list_unittest.cc

#include <gtest/gtest.h>

#include "common/LinkedList.h"

#include <list>

class Node : public LinkNode<Node> {
  public:
    explicit Node(int id) : id_(id) {
    }

    int id() const {
        return id_;
    }

  private:
    int id_;
};

class MultipleInheritanceNodeBase {
  public:
    MultipleInheritanceNodeBase() : field_taking_up_space_(0) {
    }
    int field_taking_up_space_;
};

class MultipleInheritanceNode : public MultipleInheritanceNodeBase,
                                public LinkNode<MultipleInheritanceNode> {
  public:
    MultipleInheritanceNode() = default;
};

class MovableNode : public LinkNode<MovableNode> {
  public:
    explicit MovableNode(int id) : id_(id) {
    }

    MovableNode(MovableNode&&) = default;

    int id() const {
        return id_;
    }

  private:
    int id_;
};

// Checks that when iterating |list| (either from head to tail, or from
// tail to head, as determined by |forward|), we get back |node_ids|,
// which is an array of size |num_nodes|.
void ExpectListContentsForDirection(const LinkedList<Node>& list,
                                    int num_nodes,
                                    const int* node_ids,
                                    bool forward) {
    int i = 0;
    for (const LinkNode<Node>* node = (forward ? list.head() : list.tail()); node != list.end();
         node = (forward ? node->next() : node->previous())) {
        ASSERT_LT(i, num_nodes);
        int index_of_id = forward ? i : num_nodes - i - 1;
        EXPECT_EQ(node_ids[index_of_id], node->value()->id());
        ++i;
    }
    EXPECT_EQ(num_nodes, i);
}

void ExpectListContents(const LinkedList<Node>& list, int num_nodes, const int* node_ids) {
    {
        SCOPED_TRACE("Iterating forward (from head to tail)");
        ExpectListContentsForDirection(list, num_nodes, node_ids, true);
    }
    {
        SCOPED_TRACE("Iterating backward (from tail to head)");
        ExpectListContentsForDirection(list, num_nodes, node_ids, false);
    }
}

TEST(LinkedList, Empty) {
    LinkedList<Node> list;
    EXPECT_EQ(list.end(), list.head());
    EXPECT_EQ(list.end(), list.tail());
    ExpectListContents(list, 0, nullptr);
}

TEST(LinkedList, Append) {
    LinkedList<Node> list;
    ExpectListContents(list, 0, nullptr);

    Node n1(1);
    list.Append(&n1);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n1, list.tail());
    {
        const int expected[] = {1};
        ExpectListContents(list, 1, expected);
    }

    Node n2(2);
    list.Append(&n2);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n2, list.tail());
    {
        const int expected[] = {1, 2};
        ExpectListContents(list, 2, expected);
    }

    Node n3(3);
    list.Append(&n3);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n3, list.tail());
    {
        const int expected[] = {1, 2, 3};
        ExpectListContents(list, 3, expected);
    }
}

TEST(LinkedList, RemoveFromList) {
    LinkedList<Node> list;

    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);
    Node n5(5);

    list.Append(&n1);
    list.Append(&n2);
    list.Append(&n3);
    list.Append(&n4);
    list.Append(&n5);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n5, list.tail());
    {
        const int expected[] = {1, 2, 3, 4, 5};
        ExpectListContents(list, 5, expected);
    }

    // Remove from the middle.
    n3.RemoveFromList();

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n5, list.tail());
    {
        const int expected[] = {1, 2, 4, 5};
        ExpectListContents(list, 4, expected);
    }

    // Remove from the tail.
    n5.RemoveFromList();

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n4, list.tail());
    {
        const int expected[] = {1, 2, 4};
        ExpectListContents(list, 3, expected);
    }

    // Remove from the head.
    n1.RemoveFromList();

    EXPECT_EQ(&n2, list.head());
    EXPECT_EQ(&n4, list.tail());
    {
        const int expected[] = {2, 4};
        ExpectListContents(list, 2, expected);
    }

    // Empty the list.
    n2.RemoveFromList();
    n4.RemoveFromList();

    ExpectListContents(list, 0, nullptr);
    EXPECT_EQ(list.end(), list.head());
    EXPECT_EQ(list.end(), list.tail());

    // Fill the list once again.
    list.Append(&n1);
    list.Append(&n2);
    list.Append(&n3);
    list.Append(&n4);
    list.Append(&n5);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n5, list.tail());
    {
        const int expected[] = {1, 2, 3, 4, 5};
        ExpectListContents(list, 5, expected);
    }
}

TEST(LinkedList, InsertBefore) {
    LinkedList<Node> list;

    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);

    list.Append(&n1);
    list.Append(&n2);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n2, list.tail());
    {
        const int expected[] = {1, 2};
        ExpectListContents(list, 2, expected);
    }

    n3.InsertBefore(&n2);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n2, list.tail());
    {
        const int expected[] = {1, 3, 2};
        ExpectListContents(list, 3, expected);
    }

    n4.InsertBefore(&n1);

    EXPECT_EQ(&n4, list.head());
    EXPECT_EQ(&n2, list.tail());
    {
        const int expected[] = {4, 1, 3, 2};
        ExpectListContents(list, 4, expected);
    }
}

TEST(LinkedList, InsertAfter) {
    LinkedList<Node> list;

    Node n1(1);
    Node n2(2);
    Node n3(3);
    Node n4(4);

    list.Append(&n1);
    list.Append(&n2);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n2, list.tail());
    {
        const int expected[] = {1, 2};
        ExpectListContents(list, 2, expected);
    }

    n3.InsertAfter(&n2);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n3, list.tail());
    {
        const int expected[] = {1, 2, 3};
        ExpectListContents(list, 3, expected);
    }

    n4.InsertAfter(&n1);

    EXPECT_EQ(&n1, list.head());
    EXPECT_EQ(&n3, list.tail());
    {
        const int expected[] = {1, 4, 2, 3};
        ExpectListContents(list, 4, expected);
    }
}

TEST(LinkedList, MultipleInheritanceNode) {
    MultipleInheritanceNode node;
    EXPECT_EQ(&node, node.value());
}

TEST(LinkedList, EmptyListIsEmpty) {
    LinkedList<Node> list;
    EXPECT_TRUE(list.empty());
}

TEST(LinkedList, NonEmptyListIsNotEmpty) {
    LinkedList<Node> list;

    Node n(1);
    list.Append(&n);

    EXPECT_FALSE(list.empty());
}

TEST(LinkedList, EmptiedListIsEmptyAgain) {
    LinkedList<Node> list;

    Node n(1);
    list.Append(&n);
    n.RemoveFromList();

    EXPECT_TRUE(list.empty());
}

TEST(LinkedList, NodesCanBeReused) {
    LinkedList<Node> list1;
    LinkedList<Node> list2;

    Node n(1);
    list1.Append(&n);
    n.RemoveFromList();
    list2.Append(&n);

    EXPECT_EQ(list2.head()->value(), &n);
}

TEST(LinkedList, RemovedNodeHasNullNextPrevious) {
    LinkedList<Node> list;

    Node n(1);
    list.Append(&n);
    n.RemoveFromList();

    EXPECT_EQ(nullptr, n.next());
    EXPECT_EQ(nullptr, n.previous());
}

TEST(LinkedList, NodeMoveConstructor) {
    LinkedList<MovableNode> list;

    MovableNode n1(1);
    MovableNode n2(2);
    MovableNode n3(3);

    list.Append(&n1);
    list.Append(&n2);
    list.Append(&n3);

    EXPECT_EQ(&n1, n2.previous());
    EXPECT_EQ(&n2, n1.next());
    EXPECT_EQ(&n3, n2.next());
    EXPECT_EQ(&n2, n3.previous());
    EXPECT_EQ(2, n2.id());

    MovableNode n2_new(std::move(n2));

    EXPECT_EQ(nullptr, n2.next());
    EXPECT_EQ(nullptr, n2.previous());

    EXPECT_EQ(&n1, n2_new.previous());
    EXPECT_EQ(&n2_new, n1.next());
    EXPECT_EQ(&n3, n2_new.next());
    EXPECT_EQ(&n2_new, n3.previous());
    EXPECT_EQ(2, n2_new.id());
}

TEST(LinkedList, IsInList) {
    LinkedList<Node> list;

    Node n(1);

    EXPECT_FALSE(n.IsInList());
    list.Append(&n);
    EXPECT_TRUE(n.IsInList());
    n.RemoveFromList();
    EXPECT_FALSE(n.IsInList());
}
