import java.util.*;

public class TestImmutableSet {

  public static void main(String[] args) {

    List<Integer> ints = new ArrayList<Integer>();
    for(int i = 0; i < 3; i++) ints.add(i);
    ImmutableSet<Integer> s1 = new ImmutableSet<Integer>(ints);
    System.out.println("s1 = " + s1);

    ints = new ArrayList<Integer>();
    for(int i = 2; i > -1; i--) ints.add(i);
    ImmutableSet<Integer> s2 = new ImmutableSet<Integer>(ints);
    System.out.println("s2 = " + s2);

    /* ===================== equals test ===================== */

    System.out.println("s1.equals(s2) = " + s1.equals(s2));
    System.out.println("s2.equals(s1) = " + s2.equals(s1));

    if (s1.equals(s2)) {
      System.out.println("PASS s1.equals(s2) test");
    } else {
      System.out.println("FAIL s1.equals(s2) test");
    }
    if (s2.equals(s1)) {
      System.out.println("PASS s2.equals(s1) test");
    } else {
      System.out.println("FAIL s2.equals(s1) test");
    }


    ints = new ArrayList<Integer>();
    for(int i = 3; i > -1; i--) ints.add(i);
    ImmutableSet<Integer> s3 = new ImmutableSet<Integer>(ints);
    System.out.println("s3 = " + s3);

    System.out.println("s1.equals(s3) = " + s1.equals(s3));
    System.out.println("s3.equals(s1) = " + s3.equals(s1));

    if (s1.equals(s3)) {
      System.out.println("FAIL s1.equals(s3) test");
    } else {
      System.out.println("PASS s1.equals(s3) test");
    }
    if (s3.equals(s1)) {
      System.out.println("FAIL s3.equals(s1) test");
    } else {
      System.out.println("PASS s3.equals(s1) test");
    }


    ImmutableSet<Object> s4 = new ImmutableSet<Object>(ints);
    System.out.println("s4 = " + s4);
    System.out.println("s4.equals(s3) = " + s4.equals(s3));
    System.out.println("s3.equals(s4) = " + s3.equals(s4));


    if (s3.equals(s4)) {
      System.out.println("PASS s3.equals(s4) test");
    } else {
      System.out.println("FAIL s3.equals(s4) test");
    }
    if (s4.equals(s3)) {
      System.out.println("PASS s4.equals(s3) test");
    } else {
      System.out.println("FAIL s4.equals(s3) test");
    }



    /* ===================== add test ===================== */
    int s4size = s4.size();
    try {
      s4.add("test");
      System.out.println("should not be able to add to s4???");
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    if (s4size == s4.size()) {
      System.out.println("PASS s4 add test");
    } else {
      System.out.println("FAIL s4 add test");
    }

    /* ===================== clear test ===================== */	
	
    int s3size = s3.size();
    try {
      s3.clear();
      System.out.println("should not be able to clear s3???");
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    if (s3size == s3.size()) {
      System.out.println("PASS s3 clear test");
    } else {
      System.out.println("FAIL s3 clear test");
    }


    /* ===================== containsAll test ===================== */	

    System.out.println("s3.containsAll(s1) = " + s3.containsAll(s1));

    if (s3.containsAll(s1)) {
      System.out.println("PASS s3.containsAll(s1) test");
    } else {
      System.out.println("FAIL s3.containsAll(s1) test");
    }

    /* ===================== hashCode test ===================== */	

    System.out.println("s1.hashCode() = " + s1.hashCode());
    System.out.println("s2.hashCode() = " + s2.hashCode());
    System.out.println("s3.hashCode() = " + s3.hashCode());
    System.out.println("s4.hashCode() = " + s4.hashCode());

    if (s1.hashCode() == s2.hashCode()) {
      System.out.println("PASS s1.hashCode()==s2.hashCode() test");
    } else {
      System.out.println("FAIL s1.hashCode()==s2.hashCode() test");
    }

    if (s3.hashCode() == s4.hashCode()) {
      System.out.println("PASS s3.hashCode()==s4.hashCode() test");
    } else {
      System.out.println("FAIL s3.hashCode()==s4.hashCode() test");
    }


    for(Integer i: s1) System.out.println("s1: " + i);


    /* ===================== remove test ===================== */	

    try {
      s4.remove(0);
      System.out.println("should not be able to remove from s4???");
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    if (s4.contains(0)) {
      System.out.println("PASS s4.remove(0) test");
    } else {
      System.out.println("FAIL s4.remove(0) test");
    }

    /* ===================== toArray test ===================== */	


    System.out.println(Arrays.toString(s3.toArray()));

    if (Arrays.equals(s3.toArray(),new Object[]{0,1,2,3})) {
      System.out.println("PASS s3.toArray() test");
    } else {
      System.out.println("FAIL s3.toArray() test");
    }

    Integer[] integerArray = new Integer[s3.size()];
    System.out.println(Arrays.toString(s3.toArray(integerArray)));

    if (Arrays.equals(s3.toArray(integerArray),new Integer[]{0,1,2,3})) {
      System.out.println("PASS integer s3.toArray() test");
    } else {
      System.out.println("FAIL integer s3.toArray() test");
    }

    if (s3.toArray(integerArray) == integerArray) {
      System.out.println("PASS integer == s3.toArray() test");
    } else {
      System.out.println("FAIL integer == s3.toArray() test");
    }


    /* ===================== retainAll test ===================== */	

    try {
      s3.retainAll(s1);
      System.out.println("should not be able to retainAll for s3???");
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    if (s3size == s3.size()) {
      System.out.println("PASS s3.retainAll(s1) test");
    } else {
      System.out.println("FAIL s3.retainAll(s1) test");
    }
      

    try {
      s4.retainAll(s1);
      System.out.println("should not be able to retainAll for s4???");
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    if (s4size == s4.size()) {
      System.out.println("PASS s4.retainAll(s1) test");
    } else {
      System.out.println("FAIL s4.retainAll(s1) test");
    }
      
    /* ===================== ??? test ===================== */	

    List<Object> objects = new ArrayList<Object>();
    for(int i = 0; i < 3; i++) objects.add(String.valueOf(i));
    ImmutableSet<Object> s5 = new ImmutableSet<Object>(objects);
    System.out.println("s5 = " + s5);

    Set<Object> objectSet = new TreeSet<Object>();
    for(int i = 0; i < 3; i++) objectSet.add(String.valueOf(i));
    System.out.println("s5.equals(objectSet) = " + s5.equals(objectSet));
    System.out.println("objectSet.equals(s5) = " + objectSet.equals(s5));

    if (s5.equals(objectSet)) {
      System.out.println("PASS s5.equals(objectSet) test");
    } else {
      System.out.println("FAIL s5.equals(objectSet) test");
    }

    if (objectSet.equals(s5)) {
      System.out.println("PASS objectSet.equals(s5) test");
    } else {
      System.out.println("FAIL objectSet.equals(s5) test");
    }

  }
      
}
