/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkRandom.h"
#include "SkTInternalLList.h"
#include "SkTLList.h"
#include "Test.h"

class ListElement {
public:
    ListElement(int id) : fID(id) {
    }
    bool operator== (const ListElement& other) { return fID == other.fID; }

    int fID;

private:

    SK_DECLARE_INTERNAL_LLIST_INTERFACE(ListElement);
};

static void check_list(const SkTInternalLList<ListElement>& list,
                       skiatest::Reporter* reporter,
                       bool empty,
                       int numElements,
                       bool in0, bool in1, bool in2, bool in3,
                       ListElement elements[4]) {

    REPORTER_ASSERT(reporter, empty == list.isEmpty());
#ifdef SK_DEBUG
    list.validate();
    REPORTER_ASSERT(reporter, numElements == list.countEntries());
    REPORTER_ASSERT(reporter, in0 == list.isInList(&elements[0]));
    REPORTER_ASSERT(reporter, in1 == list.isInList(&elements[1]));
    REPORTER_ASSERT(reporter, in2 == list.isInList(&elements[2]));
    REPORTER_ASSERT(reporter, in3 == list.isInList(&elements[3]));
#endif
}

static void test_tinternallist(skiatest::Reporter* reporter) {
    SkTInternalLList<ListElement> list;
    ListElement elements[4] = {
        ListElement(0),
        ListElement(1),
        ListElement(2),
        ListElement(3),
    };

    // list should be empty to start with
    check_list(list, reporter, true, 0, false, false, false, false, elements);

    list.addToHead(&elements[0]);

    check_list(list, reporter, false, 1, true, false, false, false, elements);

    list.addToHead(&elements[1]);
    list.addToHead(&elements[2]);
    list.addToHead(&elements[3]);

    check_list(list, reporter, false, 4, true, true, true, true, elements);

    // test out iterators
    typedef SkTInternalLList<ListElement>::Iter Iter;
    Iter iter;

    ListElement* cur = iter.init(list, Iter::kHead_IterStart);
    for (int i = 0; cur; ++i, cur = iter.next()) {
        REPORTER_ASSERT(reporter, cur->fID == 3-i);
    }

    cur = iter.init(list, Iter::kTail_IterStart);
    for (int i = 0; cur; ++i, cur = iter.prev()) {
        REPORTER_ASSERT(reporter, cur->fID == i);
    }

    // remove middle, frontmost then backmost
    list.remove(&elements[1]);
    list.remove(&elements[3]);
    list.remove(&elements[0]);

    check_list(list, reporter, false, 1, false, false, true, false, elements);

    // remove last element
    list.remove(&elements[2]);

    // list should be empty again
    check_list(list, reporter, true, 0, false, false, false, false, elements);

    // test out methods that add to the middle of the list.
    list.addAfter(&elements[1], nullptr);
    check_list(list, reporter, false, 1, false, true, false, false, elements);

    list.remove(&elements[1]);

    list.addBefore(&elements[1], nullptr);
    check_list(list, reporter, false, 1, false, true, false, false, elements);

    list.addBefore(&elements[0], &elements[1]);
    check_list(list, reporter, false, 2, true, true, false, false, elements);

    list.addAfter(&elements[3], &elements[1]);
    check_list(list, reporter, false, 3, true, true, false, true, elements);

    list.addBefore(&elements[2], &elements[3]);
    check_list(list, reporter, false, 4, true, true, true, true, elements);

    cur = iter.init(list, Iter::kHead_IterStart);
    for (int i = 0; cur; ++i, cur = iter.next()) {
        REPORTER_ASSERT(reporter, cur->fID == i);
    }
}

template <unsigned int N> static void test_tllist(skiatest::Reporter* reporter) {
    typedef SkTLList<ListElement, N> ElList;
    typedef typename ElList::Iter Iter;
    SkRandom random;

    ElList list1;
    ElList list2;
    Iter iter1;
    Iter iter2;
    Iter iter3;
    Iter iter4;

    REPORTER_ASSERT(reporter, list1.isEmpty());
    REPORTER_ASSERT(reporter, nullptr == iter1.init(list1, Iter::kHead_IterStart));
    REPORTER_ASSERT(reporter, nullptr == iter1.init(list1, Iter::kTail_IterStart));
    // Try popping an empty list
    list1.popHead();
    list1.popTail();
    REPORTER_ASSERT(reporter, list1.isEmpty());
    REPORTER_ASSERT(reporter, list1 == list2);

    // Create two identical lists, one by appending to head and the other to the tail.
    list1.addToHead(ListElement(1));
    list2.addToTail(ListElement(1));
    iter1.init(list1, Iter::kHead_IterStart);
    iter2.init(list1, Iter::kTail_IterStart);
    REPORTER_ASSERT(reporter, iter1.get()->fID == iter2.get()->fID);
    iter3.init(list2, Iter::kHead_IterStart);
    iter4.init(list2, Iter::kTail_IterStart);
    REPORTER_ASSERT(reporter, iter3.get()->fID == iter1.get()->fID);
    REPORTER_ASSERT(reporter, iter4.get()->fID == iter1.get()->fID);
    REPORTER_ASSERT(reporter, list1 == list2);

    list2.reset();

    // use both before/after in-place construction on an empty list
    list2.addBefore(list2.headIter(), 1);
    REPORTER_ASSERT(reporter, list2 == list1);
    list2.reset();

    list2.addAfter(list2.tailIter(), 1);
    REPORTER_ASSERT(reporter, list2 == list1);

    // add an element to the second list, check that iters are still valid
    iter3.init(list2, Iter::kHead_IterStart);
    iter4.init(list2, Iter::kTail_IterStart);
    list2.addToHead(ListElement(2));

    REPORTER_ASSERT(reporter, iter3.get()->fID == iter1.get()->fID);
    REPORTER_ASSERT(reporter, iter4.get()->fID == iter1.get()->fID);
    REPORTER_ASSERT(reporter, 1 == Iter(list2, Iter::kTail_IterStart).get()->fID);
    REPORTER_ASSERT(reporter, 2 == Iter(list2, Iter::kHead_IterStart).get()->fID);
    REPORTER_ASSERT(reporter, list1 != list2);
    list1.addToHead(ListElement(2));
    REPORTER_ASSERT(reporter, list1 == list2);
    REPORTER_ASSERT(reporter, !list1.isEmpty());

    list1.reset();
    list2.reset();
    REPORTER_ASSERT(reporter, list1.isEmpty() && list2.isEmpty());

    // randomly perform insertions and deletions on a list and perform tests
    int count = 0;
    for (int j = 0; j < 100; ++j) {
        if (list1.isEmpty() || random.nextBiasedBool(3  * SK_Scalar1 / 4)) {
            int id = j;
            // Choose one of three ways to insert a new element: at the head, at the tail,
            // before a random element, after a random element
            int numValidMethods = 0 == count ? 2 : 4;
            int insertionMethod = random.nextULessThan(numValidMethods);
            switch (insertionMethod) {
                case 0:
                    list1.addToHead(ListElement(id));
                    break;
                case 1:
                    list1.addToTail(ListElement(id));
                    break;
                case 2: // fallthru to share code that picks random element.
                case 3: {
                    int n = random.nextULessThan(list1.count());
                    Iter iter = list1.headIter();
                    // remember the elements before/after the insertion point.
                    while (n--) {
                        iter.next();
                    }
                    Iter prev(iter);
                    Iter next(iter);
                    next.next();
                    prev.prev();

                    SkASSERT(iter.get());
                    // insert either before or after the iterator, then check that the
                    // surrounding sequence is correct.
                    if (2 == insertionMethod) {
                        list1.addBefore(iter, id);
                        Iter newItem(iter);
                        newItem.prev();
                        REPORTER_ASSERT(reporter, newItem.get()->fID == id);

                        if (next.get()) {
                            REPORTER_ASSERT(reporter, next.prev()->fID == iter.get()->fID);
                        }
                        if (prev.get()) {
                            REPORTER_ASSERT(reporter, prev.next()->fID == id);
                        }
                    } else {
                        list1.addAfter(iter, id);
                        Iter newItem(iter);
                        newItem.next();
                        REPORTER_ASSERT(reporter, newItem.get()->fID == id);

                        if (next.get()) {
                            REPORTER_ASSERT(reporter, next.prev()->fID == id);
                        }
                        if (prev.get()) {
                            REPORTER_ASSERT(reporter, prev.next()->fID == iter.get()->fID);
                        }
                    }
                }
            }
            ++count;
        } else {
            // walk to a random place either forward or backwards and remove.
            int n = random.nextULessThan(list1.count());
            typename Iter::IterStart start;
            ListElement* (Iter::*incrFunc)();

            if (random.nextBool()) {
                start = Iter::kHead_IterStart;
                incrFunc = &Iter::next;
            } else {
                start = Iter::kTail_IterStart;
                incrFunc = &Iter::prev;
            }

            // find the element
            Iter iter(list1, start);
            while (n--) {
                REPORTER_ASSERT(reporter, iter.get());
                (iter.*incrFunc)();
            }
            REPORTER_ASSERT(reporter, iter.get());

            // remember the prev and next elements from the element to be removed
            Iter prev = iter;
            Iter next = iter;
            prev.prev();
            next.next();
            list1.remove(iter.get());

            // make sure the remembered next/prev iters still work
            Iter pn = prev; pn.next();
            Iter np = next; np.prev();
            // pn should match next unless the target node was the head, in which case prev
            // walked off the list.
            REPORTER_ASSERT(reporter, pn.get() == next.get() || nullptr == prev.get());
            // Similarly, np should match prev unless next originally walked off the tail.
            REPORTER_ASSERT(reporter, np.get() == prev.get() || nullptr == next.get());
            --count;
        }
        REPORTER_ASSERT(reporter, count == list1.count());
    }
}

DEF_TEST(LList, reporter) {
    test_tinternallist(reporter);
    test_tllist<1>(reporter);
    test_tllist<3>(reporter);
    test_tllist<8>(reporter);
    test_tllist<10>(reporter);
    test_tllist<16>(reporter);
}
