import java.util.*;
import nz.util.*;
import java.io.*;

public class TestTrie {
    public static void main(String [] args) {
	TrieStringSet ts = new TrieStringSet();

	ts.add("foo");
	ts.add("ziring");
	ts.add("bar");
	ts.add("baz");
	ts.add("food");
	ts.add("pizza");
	ts.add("fun");
	ts.add("fillubuster");
	ts.add("food");
	ts.add("filly");
	ts.add("cheesesteak");
	ts.add("chicken");
	ts.add("neal");
	ts.add("ziring");
	ts.add("near");
	ts.add("near");
	ts.add("chickens");
	System.out.println("Added 17 strings to set, unique size=" + ts.size());

	if (ts.add("neal")) 
	    System.out.println("add return test 1: failed");
	else 
	    System.out.println("add return test 1: ok");

	if (ts.contains("chicken"))
	    System.out.println("contains test 1: ok");
	else
	    System.out.println("contains test 1: failed");

	if (ts.contains("turkey"))
	    System.out.println("contains test 2: failed");
	else
	    System.out.println("contains test 2: ok");

	if (ts.contains("bar"))
	    System.out.println("contains test 3: ok");
	else
	    System.out.println("contains test 3: failed");

	if (ts.contains("bark"))
	    System.out.println("contains test 4: failed");
	else
	    System.out.println("contains test 4: ok");

	if (ts.contains("")) 
	    System.out.println("contains test 5: failed");
	else
	    System.out.println("contains test 5: ok");

	TrieStringSet ts2 = new TrieStringSet();
	ts2.add("SAUCY");
	ts2.add("KIWI");
	ts2.add("KUMARI");
	ts2.add("SIDNEY");
	ts2.add("BOOGER");
	ts2.add("YOSHI");

	if (ts2.contains("YOSHI")) {
	    ts2.remove("YOSHI");
	    if (ts2.contains("YOSHI")) {
		System.out.println("Contains/Remove joint test: failed(c2)");
	    }
	    else {
		if (ts2.size() != 5) {
		    System.out.println("Contains/Remove joint test: failed(s)");
		}
		else
		    System.out.println("Contains/Remove joint test: ok");
	    }
	}
	else {
	    System.out.println("Contains/Remove joint test: failed(c1)");
	}

	ts.addAll(ts2);
	System.out.println("Added a 5-element set to original set.");

	System.out.println("Size of set should now be 19: size=" + ts.size());

	if (ts.containsPrefix("chick"))
	    System.out.println("contains prefix test 1: ok");
	else
	    System.out.println("contains prefix test 1: failed");

	if (ts.containsPrefix("snicker"))
	    System.out.println("contains prefix test 2: failed");
	else
	    System.out.println("contains prefix test 2: ok");

	if (ts.containsPrefix("BOOGER"))
	    System.out.println("contains prefix test 3: ok");
	else
	    System.out.println("contains prefix test 3: failed");

	if (ts.containsPrefix("foodcourt"))
	    System.out.println("contains prefix test 4: failed");
	else
	    System.out.println("contains prefix test 4: ok");

	
	Iterator e;
	int i;
	for(i = 0, e = ts.iterator(); e.hasNext(); i++) {
	    String s = (String)(e.next());
	    System.out.println("    " + i + ". " + s);
	}

	Set ts3 = new TrieStringSet();
	Set hs3 = new HashSet();
	Set rs3 = new TreeSet();
	System.out.println("Free memory size is currently: " +
			   Runtime.getRuntime().freeMemory());
	if (args.length > 0) {
	    String filename = args[0];
	    System.out.println("File name to read is: " + filename);
	    ArrayList words;
	    try {
		BufferedReader br = new BufferedReader(new FileReader(filename));

		String s;
	        i = 1;
		for(s = br.readLine(); s != null; s = br.readLine(), i++) {
		    ts3.add(s);
		    hs3.add(s);
		    rs3.add(s);
		    if ((i % 1000) == 0) {
			System.out.print(i);
			System.out.print("/");
			System.out.print(PagedArray.pageCountTotal);
			System.out.print("\r");
		    }
		}
		System.out.println("\nLoaded " + i + " strings into set; unique size=" + ts3.size());
		br.close();


		long starttime, endtime;
		String v;
		int ccnt = 0;
		int rcnt = 0;
		char [] perm = new char[5];

		System.out.println("\nIterator Performance Test - this tests the speed of the Set\nIterator and the contains operation.\n");
		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(i = 0, e = ts3.iterator(); e.hasNext(); i++) {
		    v = (String)(e.next());
		    if ((i % 2) == 0) {
			if (!(ts3.contains(v))) {
			    System.out.println("Big test failed (contains)");
			}
			else ccnt++;
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- TrieStringSet Performance:");
		System.out.print("Performance test: iteration over " + i);
		System.out.println(" elements, " + ccnt + " contains queries");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(i = 0, e = hs3.iterator(); e.hasNext(); i++) {
		    v = (String)(e.next());
		    if ((i % 2) == 0) {
			if (!(hs3.contains(v))) {
			    System.out.println("Big test failed (contains)");
			}
			else ccnt++;
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- HashSet Performance:");
		System.out.print("Performance test: iteration over " + i);
		System.out.println(" elements, " + ccnt + " contains queries");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(i = 0, e = rs3.iterator(); e.hasNext(); i++) {
		    v = (String)(e.next());
		    if ((i % 2) == 0) {
			if (!(rs3.contains(v))) {
			    System.out.println("Big test failed (contains)");
			}
			else ccnt++;
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- TreeSet Performance:");
		System.out.print("Performance test: iteration over " + i);
		System.out.println(" elements, " + ccnt + " contains queries");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

		System.out.println("\nPermutation Queries Performance Test - this tests the speed of\nthe contains and remove operations on short strings.\n");
		starttime = System.currentTimeMillis();
		char first[] = { 'T', 'a', 'w', 'z' };
		int x0, x1, x2, x3, x4;

		/*		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(x0 = 0; x0 < 4; x0++) {
		    perm[0] = first[x0];
		    for(x1 = (int)'a'; x1 < (int)'z'; x1++) {
			perm[1] = (char)x1;
			for(x2 = (int)'a'; x2 < (int)'z'; x2 += 2) {
			    perm[2] = (char)x2;
			    for(x3 = (int)'b'; x3 < (int)'z'; x3 += 2) {
				perm[3] = (char)x3;
				for(x4 = (int)'a'; x4 < (int)'z'; x4 += 1) {
				    perm[4] = (char)x4;
				    ccnt++;
				    if (ts3.contains(v = new String(perm))) {
					rcnt++;
					ts3.remove(v);
				    }
				}		
			    }
			}		    
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- TrieStringSet Performance (normal case):");
		System.out.print("Performance test: built perms, did " + ccnt + " contains queries,");
		System.out.println(" " + rcnt + " found.");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");
		*/

		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(x0 = 0; x0 < 4; x0++) {
		    perm[0] = first[x0];
		    for(x1 = (int)'a'; x1 < (int)'z'; x1++) {
			perm[1] = (char)x1;
			for(x2 = (int)'a'; x2 < (int)'z'; x2 += 2) {
			    perm[2] = (char)x2;
			    for(x3 = (int)'b'; x3 < (int)'z'; x3 += 2) {
				perm[3] = (char)x3;
				for(x4 = (int)'a'; x4 < (int)'z'; x4 += 1) {
				    perm[4] = (char)x4;
				    ccnt++;
				    v = new String(perm);
				    if (ts3.contains(perm)) {
					rcnt++;
					ts3.remove(v);
				    }
				}		
			    }
			}		    
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- TrieStringSet Performance (best case):");
		System.out.print("Performance test: built perms, did " + ccnt + " contains queries.");
		System.out.println(" " + rcnt + " found.");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(x0 = 0; x0 < 4; x0++) {
		    perm[0] = first[x0];
		    for(x1 = (int)'a'; x1 < (int)'z'; x1++) {
			perm[1] = (char)x1;
			for(x2 = (int)'a'; x2 < (int)'z'; x2 += 2) {
			    perm[2] = (char)x2;
			    for(x3 = (int)'b'; x3 < (int)'z'; x3 += 2) {
				perm[3] = (char)x3;
				for(x4 = (int)'a'; x4 < (int)'z'; x4 += 1) {
				    perm[4] = (char)x4;
				    ccnt++;
				    if (hs3.contains(v = new String(perm))) {
					rcnt++;
					hs3.remove(v);
				    }
				}		
			    }
			}		    
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- HashSet Performance:");
		System.out.print("Performance test: built perms, did " + ccnt + " contains queries.");
		System.out.println(" " + rcnt + " found.");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

		starttime = System.currentTimeMillis();
		ccnt = 0;
		rcnt = 0;
		for(x0 = 0; x0 < 4; x0++) {
		    perm[0] = first[x0];
		    for(x1 = (int)'a'; x1 < (int)'z'; x1++) {
			perm[1] = (char)x1;
			for(x2 = (int)'a'; x2 < (int)'z'; x2 += 2) {
			    perm[2] = (char)x2;
			    for(x3 = (int)'b'; x3 < (int)'z'; x3 += 2) {
				perm[3] = (char)x3;
				for(x4 = (int)'a'; x4 < (int)'z'; x4 += 1) {
				    perm[4] = (char)x4;
				    ccnt++;
				    v = new String(perm);
				    if (rs3.contains(v)) {
					rcnt++;
					rs3.remove(v);
				    }
				}		
			    }
			}		    
		    }
		}
		endtime = System.currentTimeMillis();

		System.out.println("-- TreeSet Performance:");
		System.out.print("Performance test: built perms, did " + ccnt + " contains queries.");
		System.out.println(" " + rcnt + " found.");
		System.out.println("Total time: " + (endtime - starttime) + "ms.");

	    }
	    catch (IOException ie) {
		System.out.println("Could not open file: " + e);
	    }
	    
	}
	else {
	    System.out.println("About to perform serialization test..");
	    String fn = "testser.out";
	    ObjectOutputStream oos = null;
	    ObjectInputStream ois = null;
	    try {
		oos = new ObjectOutputStream(new FileOutputStream(fn));
		oos.writeObject(ts);
		System.out.println("Serialization write test: ok");
	    }
	    catch (IOException sie) {
		System.out.println("Serialization write test: failed - " + sie);
	    }

	    if (oos != null) try {
		oos.close();
		ois = new ObjectInputStream(new FileInputStream(fn));
		Object ro = ois.readObject();
		if (ro instanceof TrieStringSet &&
		    ((TrieStringSet)ro).contains("food") &&
		    !((TrieStringSet)ro).contains("drink") &&
		    ((TrieStringSet)ro).add("beverages"))
		    {
			System.out.println("Serialization read test: ok");
		    }
		else {
		    System.out.println("Serialization read test: failed");
		}
		ois.close();
	    }
	    catch (Exception soe) {
		System.out.println("Serialization read test: failed - " + soe);
	    }
	}
		
    }

}
