/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "tests.h"

#include <string.h>
#include <stdarg.h>

#include "jscntxt.h"
#include "jsgc.h"

#include "gc/FindSCCs.h"

#include "gc/FindSCCs-inl.h"

static const unsigned MaxVertices = 10;

using js::gc::GraphNodeBase;
using js::gc::ComponentFinder;

struct TestNode : public GraphNodeBase<TestNode>
{
    unsigned   index;
    bool       hasEdge[MaxVertices];

    void findOutgoingEdges(ComponentFinder<TestNode> &finder);
};

static TestNode Vertex[MaxVertices];

void
TestNode::findOutgoingEdges(ComponentFinder<TestNode> &finder)
{
    for (unsigned i = 0; i < MaxVertices; ++i) {
        if (hasEdge[i])
            finder.addEdgeTo(&Vertex[i]);
    }
}

BEGIN_TEST(testFindSCCs)
{
    // no vertices

    setup(0);
    run();
    CHECK(end());

    // no edges

    setup(1);
    run();
    CHECK(group(0, -1));
    CHECK(end());

    setup(3);
    run();
    CHECK(group(2, -1));
    CHECK(group(1, -1));
    CHECK(group(0, -1));
    CHECK(end());

    // linear

    setup(3);
    edge(0, 1);
    edge(1, 2);
    run();
    CHECK(group(0, -1));
    CHECK(group(1, -1));
    CHECK(group(2, -1));
    CHECK(end());

    // tree

    setup(3);
    edge(0, 1);
    edge(0, 2);
    run();
    CHECK(group(0, -1));
    CHECK(group(2, -1));
    CHECK(group(1, -1));
    CHECK(end());

    // cycles

    setup(3);
    edge(0, 1);
    edge(1, 2);
    edge(2, 0);
    run();
    CHECK(group(0, 1, 2, -1));
    CHECK(end());

    setup(4);
    edge(0, 1);
    edge(1, 2);
    edge(2, 1);
    edge(2, 3);
    run();
    CHECK(group(0, -1));
    CHECK(group(1, 2, -1));
    CHECK(group(3, -1));
    CHECK(end());

    // remaining

    setup(2);
    edge(0, 1);
    run();
    CHECK(remaining(0, 1, -1));
    CHECK(end());

    setup(2);
    edge(0, 1);
    run();
    CHECK(group(0, -1));
    CHECK(remaining(1, -1));
    CHECK(end());

    setup(2);
    edge(0, 1);
    run();
    CHECK(group(0, -1));
    CHECK(group(1, -1));
    CHECK(remaining(-1));
    CHECK(end());

    return true;
}

unsigned vertex_count;
ComponentFinder<TestNode> *finder;
TestNode *resultsList;

void setup(unsigned count)
{
    vertex_count = count;
    for (unsigned i = 0; i < MaxVertices; ++i) {
        TestNode &v = Vertex[i];
        v.gcNextGraphNode = NULL;
        v.index = i;
        memset(&v.hasEdge, 0, sizeof(v.hasEdge));
    }
}

void edge(unsigned src_index, unsigned dest_index)
{
    Vertex[src_index].hasEdge[dest_index] = true;
}

void run()
{
    finder = new ComponentFinder<TestNode>(rt->mainThread.nativeStackLimit);
    for (unsigned i = 0; i < vertex_count; ++i)
        finder->addNode(&Vertex[i]);
    resultsList = finder->getResultsList();
}

bool group(int vertex, ...)
{
    TestNode *v = resultsList;

    va_list ap;
    va_start(ap, vertex);
    while (vertex != -1) {
        CHECK(v != NULL);
        CHECK(v->index == unsigned(vertex));
        v = v->nextNodeInGroup();
        vertex = va_arg(ap, int);
    }
    va_end(ap);

    CHECK(v == NULL);
    resultsList = resultsList->nextGroup();
    return true;
}

bool remaining(int vertex, ...)
{
    TestNode *v = resultsList;

    va_list ap;
    va_start(ap, vertex);
    while (vertex != -1) {
        CHECK(v != NULL);
        CHECK(v->index == unsigned(vertex));
        v = (TestNode *)v->gcNextGraphNode;
        vertex = va_arg(ap, int);
    }
    va_end(ap);

    CHECK(v == NULL);
    resultsList = NULL;
    return true;
}

bool end()
{
    CHECK(resultsList == NULL);

    delete finder;
    finder = NULL;
    return true;
}
END_TEST(testFindSCCs)

struct TestNode2 : public GraphNodeBase<TestNode2>
{
    TestNode2 *edge;

    TestNode2() :
        edge(NULL)
    {
    }

    void
    findOutgoingEdges(ComponentFinder<TestNode2> &finder) {
        if (edge)
            finder.addEdgeTo(edge);
    }
};

BEGIN_TEST(testFindSCCsStackLimit)
{
    /*
     * Test what happens if recusion causes the stack to become full while
     * traversing the graph.
     *
     * The test case is a large number of vertices, almost all of which are
     * arranged in a linear chain.  The last few are left unlinked to exercise
     * adding vertices after the stack full condition has already been detected.
     *
     * Such an arrangement with no cycles would normally result in one group for
     * each vertex, but since the stack is exhasted in processing a single group
     * is returned containing all the vertices.
     */
    const unsigned max = 1000000;
    const unsigned initial = 10;

    TestNode2 *vertices = new TestNode2[max]();
    for (unsigned i = initial; i < (max - 10); ++i)
        vertices[i].edge = &vertices[i + 1];

    ComponentFinder<TestNode2> finder(rt->mainThread.nativeStackLimit);
    for (unsigned i = 0; i < max; ++i)
        finder.addNode(&vertices[i]);

    TestNode2 *r = finder.getResultsList();
    CHECK(r);
    TestNode2 *v = r;

    unsigned count = 0;
    while (v) {
        ++count;
        v = v->nextNodeInGroup();
    }
    CHECK(count == max - initial);

    count = 0;
    v = r->nextGroup();
    while (v) {
        ++count;
        CHECK(!v->nextNodeInGroup());
        v = v->nextGroup();
    }

    delete [] vertices;
    return true;
}
END_TEST(testFindSCCsStackLimit)
