package editortrees;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class EditTreeTest {

	static int points = 0;

	// Feel free to use these strings in your test cases, or not.

	static String s1 = "short string",
			s2 = "a moderately short string",
			s3 = "This string is not as short as the others",
			s4 = "This is a great, big, juicy, longer-than-the-others, string",
			s5 = "You can't always get the strings you want, "
					+ "but if you try sometimes, you just might find you get the strings you need.";

	/**
	 * The variables whose first two digits are your team number are available
	 * for your team's test cases to use. If you want to intiialize them once
	 * and for all instead of in individual test cases, put that code in
	 * setUpXY, where XY is your team number. You may use other variables, of
	 * course, but they should be local to your methods.
	 */
	EditTree t110, t111, t112, t113, t114, t115, t116, t117, t118, t119;
	EditTree t120, t121, t122, t123, t124, t125, t126, t127, t128, t129;
	EditTree t130, t131, t132, t133, t134, t135, t136, t137, t138, t139;
	EditTree t140, t141, t142, t143, t144, t145, t146, t147, t148, t149;
	EditTree t150, t151, t152, t153, t154, t155, t156, t157, t158, t159;
	EditTree t160, t161, t162, t163, t164, t165, t166, t167, t168, t169;
	EditTree t210, t211, t212, t213, t214, t215, t216, t217, t218, t219;
	EditTree t220, t221, t222, t223, t224, t225, t226, t227, t228, t229;
	EditTree t230, t231, t232, t233, t234, t235, t236, t237, t238, t239;
	EditTree t240, t241, t242, t243, t244, t245, t246, t247, t248, t249;
	EditTree t250, t251, t252, t253, t254, t255, t256, t257, t258, t259;
	EditTree t260, t261, t262, t263, t264, t265, t266, t267, t268, t269;
	EditTree ti0, ti1, ti2, ti3, ti4, ti5, ti6, ti7, ti8, ti9;

	// Do not modify this method

	@Before
	public void setUp() throws Exception {
		try {
			setUpInstructors();
		} catch (Exception e) {
			System.out.println("Error in setUpInstructors:");
			e.printStackTrace();
		}
		try {
			setUp11();
		} catch (Exception e) {
			System.out.println("Error in setUp11:");
			e.printStackTrace();
		}
		try {
			setUp12();
		} catch (Exception e) {
			System.out.println("Error in setUp12:");
			e.printStackTrace();
		}
		try {
			setUp13();
		} catch (Exception e) {
			System.out.println("Error in setUp13:");
			e.printStackTrace();
		}
		try {
			setUp14();
		} catch (Exception e) {
			System.out.println("Error in setUp14:");
			e.printStackTrace();
		}
		try {
			setUp15();
		} catch (Exception e) {
			System.out.println("Error in setUp15:");
			e.printStackTrace();
		}
		try {
			setUp16();
		} catch (Exception e) {
			System.out.println("Error in setUp16:");
			e.printStackTrace();
		}
		try {
			setUp21();
		} catch (Exception e) {
			System.out.println("Error in setUp21:");
			e.printStackTrace();
		}
		try {
			setUp22();
		} catch (Exception e) {
			System.out.println("Error in setUp22:");
			e.printStackTrace();
		}
		try {
			setUp23();
		} catch (Exception e) {
			System.out.println("Error in setUp23:");
			e.printStackTrace();
		}
		try {
			setUp24();
		} catch (Exception e) {
			System.out.println("Error in setUp24:");
			e.printStackTrace();
		}
		try {
			setUp25();
		} catch (Exception e) {
			System.out.println("Error in setUp25:");
			e.printStackTrace();
		}
		try {
			setUp26();
		} catch (Exception e) {
			System.out.println("Error in setUp26:");
			e.printStackTrace();
		}
	}

	public void setUpInstructors() throws Exception {

	}

	public void setUp11() throws Exception {

	}

	public void setUp12() throws Exception {

	}

	public void setUp13() throws Exception {

	}

	public void setUp14() throws Exception {

	}

	public void setUp15() throws Exception {

	}

	public void setUp16() throws Exception {

	}

	public void setUp21() throws Exception {

	}

	public void setUp22() throws Exception {

	}

	public void setUp23() throws Exception {

	}

	public void setUp24() throws Exception {

	}

	public void setUp25() throws Exception {

	}

	public void setUp26() throws Exception {

	}

	// The name of each of your team's tests should end with an underscore
	// followed by your team number,
	// for example, testSize3_13 if you are on team 13.

	// Make sure that each of your tests has a timeout.
	// The timeout should be 1 or 2 seconds unless your
	// test involves VERY complicated operations.

	// Each of your tests should be worth one point.

	// A sample test to remind you of the format:

	@Test(timeout = 1000)
	// one second
	public void testSize3_i() { // i is for instructor
		ti3 = new EditTree(s1);
		assertEquals(12, ti3.size());
		points += 1; // only incremented if test passes.
	}

	/*
	 * things to test Constructors: EditTree() EditTree(char c) EditTree(String
	 * s) EditTree(EditTree e)
	 * 
	 * Functions:
	 * 
	 * height()
	 * 
	 * toString()
	 * 
	 * add(char c) add(char c, int pos)
	 * 
	 * delete(int pos) delete(int start, int length)
	 * 
	 * get(int pos) get(int pos, int length)
	 * 
	 * concatenate(EditTree other)
	 * 
	 * split(int pos)
	 * 
	 * find(String s) find(String s, int pos)
	 * 
	 * isHeightBalanced()
	 * 
	 * getRoot()
	 * 
	 * checkRanks()
	 */

	@Test(timeout = 1000)
	// one second
	public void testEditTree1_11() {
		t110 = new EditTree();
		assertEquals(null, t110.getRoot());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditTree2_11() {
		t110 = new EditTree('a');
		assertEquals('a', t110.getRoot().element);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditTree3_11() {
		t110 = new EditTree(s1);
		t111 = new EditTree(s2);
		t112 = new EditTree(s3);
		t113 = new EditTree(s4);
		t114 = new EditTree(s5);
		assertEquals(s1, t110.toString());
		assertEquals(s2, t111.toString());
		assertEquals(s3, t112.toString());
		assertEquals(s4, t113.toString());
		assertEquals(s5, t114.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditTree4_11() {
		t110 = new EditTree('a');
		t111 = new EditTree(t110);
		assertEquals(t110, t111);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testHeight1_11() {
		t110 = new EditTree(s1);
		t111 = new EditTree(s2);
		t112 = new EditTree(s3);
		t113 = new EditTree('a');
		t114 = new EditTree();
		assertEquals(4, t110.height());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testadd1_11() {
		t110 = new EditTree(s1);
		assertEquals(s1, t110.toString());
		t110.add('a');
		assertEquals(s1 + 'a', t110.toString());
		t110.add(' ');
		assertEquals(s1 + 'a' + ' ', t110.toString());
		assertTrue(t110.isHeightBalanced());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testadd2_11() {
		t110 = new EditTree(s1);
		DisplayTree.display(t110);
		assertEquals(s1, t110.toString());
		t110.add('a', 5);
		assertEquals("shorta string", t110.toString());
		t110.add(' ', 10);
		assertEquals("shorta str ing", t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testgetRoot1_11() {
		t110 = new EditTree('c');
		assertEquals('c', t110.getRoot().element);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testConcatenate1_11() {
		t110 = new EditTree();
		t111 = new EditTree(s1);
		t110.concatenate(t111);
		assertEquals(s1, t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testConcatenate2_11() {
		t110 = new EditTree();
		t111 = new EditTree();
		t110.concatenate(t111);
		assertEquals(null, t110.getRoot());
		assertEquals("", t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testConcatenate3_11() {
		t110 = new EditTree(s1);
		t111 = new EditTree();
		t110.concatenate(t111);
		assertEquals(s1, t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testConcatenate4_11() {
		t110 = new EditTree(s2);
		t111 = new EditTree(s3);
		t110.concatenate(t111);
		assertEquals(s1 + s2, t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(expected = IllegalArgumentException.class)
	// expecting an illegal argument exception
	public void testConcatenate5_11() {
		t110 = new EditTree(s1);
		t110.concatenate(t110);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testSplit1_11() {
		t110 = new EditTree(s1);
		t111 = t110.split(0);
		assertEquals(s1, t111.toString());
		assertEquals("", t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testSplit2_11() {
		t110 = new EditTree(s1);
		t111 = t110.split(6);
		assertEquals("string", t111.toString());
		assertEquals("short ", t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testSplit3_11() {
		t110 = new EditTree(s1);
		t111 = t110.split(11);
		assertEquals("g", t111.toString());
		assertEquals("short strin", t110.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testSplit4_11() {
		t110 = new EditTree(s5);
		t111 = t110.split(43);
		assertEquals(
				"but if you try sometimes, you just might find you get the strings you need.",
				t111.toString());
		assertEquals("You can't always get the strings you want, ", t110
				.toString());
		points += 1; // only incremented if test passes.
	}

	@Test(expected = IndexOutOfBoundsException.class)
	// expecting an index out of bounds exception
	public void testSplit5_11() {
		t110 = new EditTree(s1);
		t110.split(-3);
		points += 1; // only incremented if test passes.
	}

	@Test(expected = IndexOutOfBoundsException.class)
	// expecting an index out of bounds exception
	public void testSplit6_11() {
		t110 = new EditTree(s1);
		t110.split(12);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind1_11() {
		t110 = new EditTree(s1);
		assertEquals(-1, t110.find(""));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind2_11() {
		t110 = new EditTree(s1);
		assertEquals(6, t110.find("string"));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind3_11() {
		t110 = new EditTree(s1);
		assertEquals(0, t110.find("s"));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind4_11() {
		t110 = new EditTree(s1);
		assertEquals(0, t110.find(s1));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind5_11() {
		t110 = new EditTree(s5);
		assertEquals(0, t110.find(s5));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind6_11() {
		t110 = new EditTree(s5);
		assertEquals(s5.length() - 1, t110.find("."));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind7_11() {
		t110 = new EditTree(s5);
		assertEquals(0, t110.find("You"));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind8_11() {
		t110 = new EditTree(s5);
		assertEquals(33, t110.find("you"));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind9_11() {
		t110 = new EditTree(s1);
		assertEquals(-1, t110.find("string", 7));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind10_11() {
		t110 = new EditTree(s1);
		assertEquals(6, t110.find("string", 6));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind11_11() {
		t110 = new EditTree(s5);
		assertEquals(50, t110.find("you", 45));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind12_11() {
		t110 = new EditTree(s1);
		assertEquals(0, t110.find(s1));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testFind13_11() {
		t110 = new EditTree(s2);
		assertEquals(-1, t110.find("csse", 0));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testIsHeightBalanced1_11() {
		t110 = new EditTree();
		Node root = t110.getRoot();
		assertTrue(isBalanced(root));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testIsHeightBalanced2_11() {
		t110 = new EditTree(s2);
		Node root = t110.getRoot();
		assertTrue(isBalanced(root));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testIsHeightBalanced3_11() {
		t110 = new EditTree(s5);
		Node root = t110.getRoot();
		assertTrue(isBalanced(root));
		points += 1; // only incremented if test passes.
	}

	public boolean isBalanced(Node n) {
		boolean rt = true, lt = true;
		int right = 0, left = 0;

		if (n.right != null) {
			right = n.right.height();
			rt = isBalanced(n.right);
		}

		if (n.left != null) {
			left = n.left.height();
			lt = isBalanced(n.left);
		}

		if (Math.abs(left - right) <= 1)
			return rt && lt;
		return false;

	}

	@Test(timeout = 1000)
	// one second
	public void testEditDelete1_11() {
		t110 = new EditTree("abc");
		EditTree correctNewTree = new EditTree("ab");
		assertEquals(correctNewTree, t110.delete(3));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditDelete2_11() {
		t110 = new EditTree("abcdefg");
		EditTree correctNewTree = new EditTree("ag");
		assertEquals(correctNewTree, t110.delete(2, 6));
		points += 1; // only incremented if test passes.
	}

	@Test(expected = IndexOutOfBoundsException.class)
	// expecting an index out of bounds exception
	public void testEditDelete3_11() {
		t110 = new EditTree("abcdefg");
		t110.delete(2, 40);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditGet1_11() {
		t110 = new EditTree(s1);
		assertEquals('o', t110.get(3));
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditGet2_11() {
		t110 = new EditTree(s3);
		assertEquals("string", t110.get(6, 11));
		points += 1; // only incremented if test passes.
	}

	@Test(expected = IndexOutOfBoundsException.class)
	// expecting an index out of bounds exception
	public void testEditGet3_11() {
		t110 = new EditTree(s2);
		t110.get(30);
		points += 1; // only incremented if test passes.
	}

	@Test(timeout = 1000)
	// one second
	public void testEditCheckRanks1_11() {
		t110 = new EditTree(s1);
		assertEquals(true, t110.checkRanks());
		points += 1; // only incremented if test passes.
	}

}