package s3.util.queues;

import ovm.core.OVMBase;
import ovm.core.services.io.BasicIO;
/**
 * Test program for SingleLinkQueue
 *
 */
// not public because we don't want it in javadoc
class QDriver {

    static class TestNode extends SingleLinkNode {

        static int nextId;
        public final int id;

        public TestNode() {
            synchronized(TestNode.class) {
                id = nextId++;
            }
        }

        public String toString() {
            return "(id=" + id + ")";
        }
    }

    // set of test nodes

    static TestNode[] n = {
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
        new TestNode(),
    };

    public static void main(String[] args) {

        BasicIO.out.println("Starting Tests");
        // start with empty queue
        SingleLinkQueue q = new SingleLinkQueue();
        OVMBase.OVMassert(q.isEmpty() && q.head()==null && q.tail()==null && q.size() == 0 , "isEmpty");
        for (int i = 0; i < n.length; i++) {
            OVMBase.OVMassert(!q.contains(n[i]) && !q.remove(n[i]) , "element found");
        }

        // now add elements checking the order etc
        for (int i = 0; i < n.length; i++) {
            q.add(n[i]);
            q.dump(BasicIO.out);
            OVMBase.OVMassert(q.size() == (i+1), "size");
            OVMBase.OVMassert(!q.isEmpty() , "not empty");
            OVMBase.OVMassert(q.tail() == n[i] , "tail");
            OVMBase.OVMassert(q.head() == n[0] , "head unchanged");
            OVMBase.OVMassert(q.head() != n[i] || q.head() == q.tail() , "not head");
            OVMBase.OVMassert(q.contains(n[i]) , "contains");
            // check order
            for (SingleLinkElement curr = q.head;
                 curr != null;
                 curr = curr.getNext()) {
                if (curr.getNext() != null) {
                    OVMBase.OVMassert( ((TestNode)curr).id + 1 == ((TestNode)curr.getNext()).id , "order");
                }
            }
        }

        // now take and check
        for (int i = 0; i < n.length; i++) {
            SingleLinkElement t1 = q.head();
            SingleLinkElement t2 = q.take();
            q.dump(BasicIO.out);
            OVMBase.OVMassert(q.size() == (n.length - (i+1)), "size");
            OVMBase.OVMassert(t1 == t2 && t2 == n[i] , "head removed");
            OVMBase.OVMassert(!q.contains(n[i]) , "not contains");
            for (int j = i+1; j < n.length; j++) {
                OVMBase.OVMassert(q.contains(n[j]) , "contains others");
            }
            OVMBase.OVMassert(q.tail() == (i == n.length-1 ? null : n[n.length-1]) , "tail unchanged");
        }

        OVMBase.OVMassert(q.isEmpty() && q.head()==null && q.tail()==null && q.size()==0 , "isEmpty");


        // finally test remove: head, tail, middle etc
        for (int i = 0; i < n.length; i++) {
            q.add(n[i]);
        }

        int[] indices = { 0, // head
                          9, // tail
                          5, // middle
                          3, // middle
                          7, // middle
                          1, // head
                          8, // tail
                          4, // middle
                          2, // head
                          6, // tail
        };
        OVMBase.OVMassert(n.length == indices.length , "arrays");
        for (int i = 0; i < n.length; i++) {
            OVMBase.OVMassert(q.contains(n[indices[i]]) , "contains");
            OVMBase.OVMassert(q.remove(n[indices[i]]) , "remove");
            OVMBase.OVMassert(q.size() == (n.length - (i+1)), "size");
            OVMBase.OVMassert(!q.contains(n[indices[i]]) , "!contains");
            for (int j = i+1; j < n.length; j++) {
                OVMBase.OVMassert(q.contains(n[indices[j]]) , "contains others");
            }
        }
        OVMBase.OVMassert(q.isEmpty() && q.head()==null && q.tail()==null , "isEmpty");


        BasicIO.out.println("Tests Completed");
    }
}




