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

#include "SkTDPQueue.h"
#include "SkRandom.h"
#include "Test.h"

namespace { bool intless(const int& a, const int& b) { return a < b; } }

static void simple_test(skiatest::Reporter* reporter) {
    SkTDPQueue<int, intless> heap;
    REPORTER_ASSERT(reporter, 0 == heap.count());

    heap.insert(0);
    REPORTER_ASSERT(reporter, 1 == heap.count());
    REPORTER_ASSERT(reporter, 0 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 0 == heap.count());

    heap.insert(0);
    heap.insert(1);
    REPORTER_ASSERT(reporter, 2 == heap.count());
    REPORTER_ASSERT(reporter, 0 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 1 == heap.count());
    REPORTER_ASSERT(reporter, 1 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 0 == heap.count());

    heap.insert(2);
    heap.insert(1);
    heap.insert(0);
    REPORTER_ASSERT(reporter, 3 == heap.count());
    REPORTER_ASSERT(reporter, 0 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 2 == heap.count());
    REPORTER_ASSERT(reporter, 1 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 1 == heap.count());
    REPORTER_ASSERT(reporter, 2 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 0 == heap.count());

    heap.insert(2);
    heap.insert(3);
    heap.insert(0);
    heap.insert(1);
    REPORTER_ASSERT(reporter, 4 == heap.count());
    REPORTER_ASSERT(reporter, 0 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 3 == heap.count());
    REPORTER_ASSERT(reporter, 1 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 2 == heap.count());
    REPORTER_ASSERT(reporter, 2 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 1 == heap.count());
    REPORTER_ASSERT(reporter, 3 == heap.peek());
    heap.pop();
    REPORTER_ASSERT(reporter, 0 == heap.count());
}

struct Dummy {
    int fValue;
    int fPriority;
    mutable int fIndex;

    static bool LessP(Dummy* const& a, Dummy* const& b) { return a->fPriority < b->fPriority; }
    static int* PQIndex(Dummy* const& dummy) { return &dummy->fIndex; }

    bool operator== (const Dummy& that) const {
        return fValue == that.fValue && fPriority == that.fPriority;
    }
    bool operator!= (const Dummy& that) const { return !(*this == that); }
};

void random_test(skiatest::Reporter* reporter) {
    SkRandom random;
    static const Dummy kSentinel = {-1, -1, -1};

    for (int i = 0; i < 100; ++i) {
        // Create a random set of Dummy objects.
        int count = random.nextULessThan(100);
        SkTDArray<Dummy> array;
        array.setReserve(count);
        for (int j = 0; j < count; ++j) {
            Dummy* dummy = array.append();
            dummy->fPriority = random.nextS();
            dummy->fValue = random.nextS();
            dummy->fIndex = -1;
            if (*dummy == kSentinel) {
                array.pop();
                --j;
            }
        }

        // Stick the dummy objects in the pqueue.
        SkTDPQueue<Dummy*, Dummy::LessP, Dummy::PQIndex> pq;
        for (int j = 0; j < count; ++j) {
            pq.insert(&array[j]);
        }
        REPORTER_ASSERT(reporter, pq.count() == array.count());
        for (int j = 0; j < count; ++j) {
            // every item should have an entry in the queue.
            REPORTER_ASSERT(reporter, -1 != array[j].fIndex);
        }

        // Begin the test.
        while (pq.count()) {
            // Make sure the top of the queue is really the highest priority.
            Dummy* top = pq.peek();
            for (int k = 0; k < count; ++k) {
                REPORTER_ASSERT(reporter, kSentinel == array[k] ||
                                            array[k].fPriority >= top->fPriority);
            }
            // Do one of three random actions:
            unsigned action = random.nextULessThan(3);
            switch (action) {
                case 0: { // pop the top,
                    Dummy* top = pq.peek();
                    REPORTER_ASSERT(reporter, array.begin() <= top && top < array.end());
                    pq.pop();
                    *top = kSentinel;
                    break;
                }
                case 1: { // remove a random element,
                    int item;
                    do {
                        item = random.nextULessThan(count);
                    } while (array[item] == kSentinel);
                    pq.remove(&array[item]);
                    array[item] = kSentinel;
                    break;
                }
                case 2: { // or change an element's priority.
                    int item;
                    do {
                        item = random.nextULessThan(count);
                    } while (array[item] == kSentinel);
                    array[item].fPriority = random.nextS();
                    pq.priorityDidChange(&array[item]);
                    break;
                }
            }
        }
   }
}

void sort_test(skiatest::Reporter* reporter) {
    SkRandom random;

    SkTDPQueue<Dummy *, Dummy::LessP, Dummy::PQIndex> pqTest;
    SkTDPQueue<Dummy *, Dummy::LessP, Dummy::PQIndex> pqControl;

    // Create a random set of Dummy objects and populate the test queue.
    int count = random.nextULessThan(100);
    SkTDArray<Dummy> testArray;
    testArray.setReserve(count);
    for (int i = 0; i < count; i++) {
        Dummy *dummy = testArray.append();
        dummy->fPriority = random.nextS();
        dummy->fValue = random.nextS();
        dummy->fIndex = -1;
        pqTest.insert(&testArray[i]);
    }

    // Stick equivalent dummy objects into the control queue.
    SkTDArray<Dummy> controlArray;
    controlArray.setReserve(count);
    for (int i = 0; i < count; i++) {
        Dummy *dummy = controlArray.append();
        dummy->fPriority = testArray[i].fPriority;
        dummy->fValue = testArray[i].fValue;
        dummy->fIndex = -1;
        pqControl.insert(&controlArray[i]);
    }

    // Sort the queue
    pqTest.sort();

    // Compare elements in the queue to ensure they are in sorted order
    int prevPriority = pqTest.peek()->fPriority;
    for (int i = 0; i < count; i++) {
        REPORTER_ASSERT(reporter, i <= pqTest.at(i)->fIndex);
        REPORTER_ASSERT(reporter, prevPriority <= pqTest.at(i)->fPriority);
        prevPriority = pqTest.at(i)->fPriority;
    }

    // Verify that after sorting the queue still produces the same result as the control queue
    for (int i = 0; i < count; i++) {
        REPORTER_ASSERT(reporter, *pqControl.peek() == *pqTest.peek());
        pqControl.pop();
        pqTest.pop();
    }
}

DEF_TEST(TDPQueueTest, reporter) {
    simple_test(reporter);
    random_test(reporter);
    sort_test(reporter);
}
