package brs.visitor.test;

import lrs.*;
import brs.*;
import brs.visitor.*;
import junit.framework.TestCase;

public class BRSTrimTest extends TestCase {
    final IVisitor bIsE = new IVisitor() {
        public Object emptyCase(BiTree host, Object... inp) {
            return true;
        }
        public Object nonEmptyCase(BiTree host, Object... inp) {
            return false;
        }
    };
    final IAlgo lIsE = new IAlgo() {
        public Object emptyCase(LRStruct host, Object... inp) {
            return true;
        }
        public Object nonEmptyCase(LRStruct host, Object... inp) {
            return false;
        }
    };
    
    public void assertEmptyTree(BiTree b) {
        assertTrue((Boolean)b.execute(bIsE));
    }
    public void assertNonEmptyTree(BiTree b) {
        assertFalse((Boolean)b.execute(bIsE));
    }
    public void assertRoot(BiTree b, int i) {
        assertNonEmptyTree(b);
        assertEquals((Integer)i, (Integer)b.getRootDat());
    }
    public void assertEmpty(LRStruct l) {
        assertTrue((Boolean)l.execute(lIsE));
    }
    public void assertNonEmpty(LRStruct l) {
        assertFalse((Boolean)l.execute(lIsE));
    }
    public void assertFirst(LRStruct l, int i) {
        assertNonEmpty(l);
        assertEquals((Integer)i, (Integer)l.getFirst());
    }
    
    public void testEmpty() {
        BiTree b = new BiTree();
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testLeaf() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
    }
    
    public void testRootLeft() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree bl = new BiTree();
        bl.insertRoot(2);
        b.setLeftSubTree(bl);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootRight() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree br = new BiTree();
        br.insertRoot(2);
        b.setRightSubTree(br);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootLeftRight() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree bl = new BiTree();
        bl.insertRoot(2);
        b.setLeftSubTree(bl);
        BiTree br = new BiTree();
        br.insertRoot(3);
        b.setRightSubTree(br);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertFirst(l.getRest(), 3);
        assertEmpty(l.getRest().getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootLeftLeft() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree bl = new BiTree();
        bl.insertRoot(2);
        b.setLeftSubTree(bl);
        BiTree bll = new BiTree();
        bll.insertRoot(3);
        bl.setLeftSubTree(bll);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertRoot(b.getLeftSubTree(), 2);
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 3);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootRightRight() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree br = new BiTree();
        br.insertRoot(2);
        b.setRightSubTree(br);
        BiTree brr = new BiTree();
        brr.insertRoot(3);
        br.setLeftSubTree(brr);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertRoot(b.getRightSubTree(), 2);
        assertFirst(l, 3);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootLeftLeftRight() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree bl = new BiTree();
        bl.insertRoot(2);
        b.setLeftSubTree(bl);
        BiTree bll = new BiTree();
        bll.insertRoot(3);
        bl.setLeftSubTree(bll);
        BiTree blr = new BiTree();
        blr.insertRoot(4);
        bl.setRightSubTree(blr);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertRoot(b.getLeftSubTree(), 2);
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 3);
        assertFirst(l.getRest(), 4);
        assertEmpty(l.getRest().getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        assertEmptyTree(b);
        assertEmpty(l);
    }
    
    public void testRootLeftLeftRightRightLeft() {
        BiTree b = new BiTree();
        b.insertRoot(1);
        BiTree bl = new BiTree();
        bl.insertRoot(2);
        b.setLeftSubTree(bl);
        BiTree bll = new BiTree();
        bll.insertRoot(3);
        bl.setLeftSubTree(bll);
        BiTree blr = new BiTree();
        blr.insertRoot(4);
        bl.setRightSubTree(blr);
        BiTree br = new BiTree();
        br.insertRoot(5);
        b.setRightSubTree(br);
        BiTree brl = new BiTree();
        brl.insertRoot(6);
        br.setLeftSubTree(brl);
        System.out.println(b);
        LRStruct l = (LRStruct)b.execute(BRSTrim.Singleton);
        System.err.println(l);
        assertRoot(b, 1);
        assertRoot(b.getLeftSubTree(), 2);
        assertRoot(b.getRightSubTree(), 5);
        assertFirst(l, 3);
        assertFirst(l.getRest(), 4);
        assertFirst(l.getRest().getRest(), 6);
        assertEmpty(l.getRest().getRest().getRest());
        System.out.println(b);
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        System.err.println(l);
        assertRoot(b, 1);
        assertEmptyTree(b.getLeftSubTree());
        assertEmptyTree(b.getRightSubTree());
        assertFirst(l, 2);
        assertFirst(l.getRest(), 5);
        assertEmpty(l.getRest().getRest());
        System.out.println(b);
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        System.err.println(l);
        assertEmptyTree(b);
        assertFirst(l, 1);
        assertEmpty(l.getRest());
        System.out.println(b);
        l = (LRStruct)b.execute(BRSTrim.Singleton);
        System.err.println(l);
        assertEmptyTree(b);
        assertEmpty(l);
    }
}
