import junit.framework.TestCase;

import lrs.*;
import lrs.lazyLRSEvaluators.*;

public class LazyListNCopiesEvalTest extends TestCase {
    private static final IAlgo isE = new IAlgo() {
        public Object emptyCase(LRStruct host, Object... inp) {
            return true;
        }
        public Object nonEmptyCase(LRStruct host, Object... inp) {
            return false;
        }
    };
    
    public static void assertEmpty(LRStruct l) {
        assertTrue((Boolean)l.execute(isE));
    }
    public static void assertNonEmpty(LRStruct l) {
        assertFalse((Boolean)l.execute(isE));
    }
    public static void assertFirst(LRStruct l, int i) {
        assertFalse((Boolean)l.execute(isE));
        assertEquals((Integer)i, (Integer)l.getFirst());
    }
    public static LRStruct toLRS(Object... o) {
        LRStruct l = new LRStruct();
        for(int i=o.length-1; i>=0; --i) {
            l.insertFront(o[i]);
        }
        return l;
    }
    
    public void testEmptyEmpty() {
        LRStruct res = new LazyListNCopiesEval(toLRS(), toLRS()).makeLRS();
        assertEmpty(res);
    }
    
    public void testEmptyNEmpty() {
        LRStruct res = new LazyListNCopiesEval(toLRS(), toLRS(1)).makeLRS();
        assertEmpty(res);
    }

    public void testNEmptyEmpty() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1), toLRS()).makeLRS();
        assertEmpty(res);
    }

    public void test1_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertEmpty(res.getRest());
    }

    public void test2_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertEmpty(res.getRest().getRest());
    }

    public void test3_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertEmpty(res.getRest().getRest().getRest());
    }
    
    public void test1_1b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1), toLRS(1, 1)).makeLRS();
        assertFirst(res, 1);
        assertEmpty(res.getRest());
    }

    public void test2_1b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2), toLRS(1, 1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertEmpty(res.getRest().getRest());
    }

    public void test3_1b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3), toLRS(1, 1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertEmpty(res.getRest().getRest().getRest());
    }
    
    public void test1b_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1, 1), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertEmpty(res.getRest());
    }

    public void test2b_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2, 1), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertEmpty(res.getRest().getRest());
    }

    public void test3b_1() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3, 1), toLRS(1)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertEmpty(res.getRest().getRest().getRest());
    }
    
    public void test2_2() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1, 1), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 2);
        assertEmpty(res.getRest().getRest());
    }

    public void test2b_2() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2, 1), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest());
    }

    public void test2c_2() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3, 1), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest());
    }
    
    public void test2_2b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1, 2), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 2);
        assertFirst(res.getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest());
    }

    public void test2b_2b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2, 2), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest());
    }

    public void test2c_2b() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3, 2), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest());
    }
    
    public void test2_2c() {
        LRStruct res = new LazyListNCopiesEval(toLRS(1, 3), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 2);
        assertFirst(res.getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest());
    }

    public void test2b_2c() {
        LRStruct res = new LazyListNCopiesEval(toLRS(2, 3), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest());
    }

    public void test2c_2c() {
        LRStruct res = new LazyListNCopiesEval(toLRS(3, 3), toLRS(1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest().getRest());
    }

    public void test0_3_3() {
        LRStruct res = new LazyListNCopiesEval(toLRS(0, 3, 3), toLRS(0, 1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest().getRest());
    }

    public void test0_0_3_3() {
        LRStruct res = new LazyListNCopiesEval(toLRS(0, 0, 3, 3), toLRS(0, 0, 1, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest().getRest());
    }

    public void test0_3_0_3() {
        LRStruct res = new LazyListNCopiesEval(toLRS(0, 3, 0, 3), toLRS(0, 1, 0, 2)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest().getRest());
    }

    public void test0_3_3_0() {
        LRStruct res = new LazyListNCopiesEval(toLRS(0, 3, 3, 0), toLRS(0, 1, 2, 0)).makeLRS();
        assertFirst(res, 1);
        assertFirst(res.getRest(), 1);
        assertFirst(res.getRest().getRest(), 1);
        assertFirst(res.getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest(), 2);
        assertFirst(res.getRest().getRest().getRest().getRest().getRest(), 2);
        assertEmpty(res.getRest().getRest().getRest().getRest().getRest().getRest());
    }
}