
public class TestList {

  static public String usage() {
    String s = "";
    s += "Usage: java TestList <test-number:1-14>\n";
    return s;
  }

  public static void main( String [] args ) {

    if ( args.length == 0 ) {
      System.out.println( usage() );
      System.exit( -1 );
    }

    if ( args[ 0 ].equals( "1" ) ) {
      System.out.println( "TestList 1: Test isEmpty() ");
      List l = new List();

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }

    }
    else if ( args[ 0 ].equals( "2" ) ) {

      System.out.println( "TestList 2: Test isEmpty()");
      List l = new List();

      l.addToFront( new TestListNode("Mickey") );

      if ( l.isEmpty() ) {
	System.out.println("Test failed: List is empty");
      }
      else {
	System.out.println("Test passed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "3" ) ) {

      System.out.println( "TestList 3: Test addToFront/removeFront 1");
      List l = new List();

      l.addToFront( new TestListNode("Mickey") );

      TestListNode n = (TestListNode) l.removeFront();
      System.out.println( "Get:" + n.name() );

      if ( !n.name().equals( "Mickey" ) ) {
	System.out.println("Test failed: Did not get Mickey");
	System.exit( -1 );
      }

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "4" ) ) {

      System.out.println( "TestList 4: Test addToFront/removeFront multiple");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToFront( new TestListNode( names[ i ] ) );
      }

      for ( int i = names.length-1; i >= 0; i-- ) {
	TestListNode n = (TestListNode) l.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
      }

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "5" ) ) {

      System.out.println( "TestList 5: Test addToTail/removeFront multiple");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = (TestListNode) l.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
      }

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "6" ) ) {

      System.out.println( "TestList 6: Test addToTail/removeTail multiple");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      for ( int i = names.length-1; i >=0; i-- ) {
	TestListNode n = (TestListNode) l.removeTail();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
      }

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "7" ) ) {

      System.out.println( "TestList 7: Test addToTail/removeFront multiple");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = (TestListNode) l.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
      }

      if ( l.isEmpty() ) {
	System.out.println("Test passed: List is empty");
      }
      else {
	System.out.println("Test failed: List is not empty");
      }
    }
    else if ( args[ 0 ].equals( "8" ) ) {

      System.out.println( "TestList 8: Test removeTail/removeFront return null");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      if ( l.removeTail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.removeFront() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = (TestListNode) l.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
      }

      if ( l.removeTail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.removeFront() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "9" ) ) {

      System.out.println( "TestList 9: Test tail/front ");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      if ( l.tail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.front() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = new TestListNode( names[ i ] );
	l.addToTail( n );

	if ( n != (TestListNode) l.tail() ) {
	  System.out.println("Test failed: Unexpected tail ");
	  System.exit( -1 );
	}
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode f = (TestListNode) (TestListNode) l.front();
	TestListNode n = (TestListNode) l.removeFront();

	System.out.println( "Get:" + n.name() );

	if ( n != f ) {
	  System.out.println("Test failed: Unexpected front ");
	  System.exit( -1 );
	}

	if ( !n.name().equals( names[i] ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}

      }

      if ( l.tail() != null ) {
	System.out.println("Test failed: tail() != null ");
	System.exit( -1 );
      }

      if ( l.front() != null ) {
	System.out.println("Test failed: front() != null ");
	System.exit( -1 );
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "10" ) ) {

      System.out.println( "TestList 10: Test clear ");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      if ( l.tail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.front() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = new TestListNode( names[ i ] );
	l.addToTail( n );

	if ( n != (TestListNode) l.tail() ) {
	  System.out.println("Test failed: Unexpected tail ");
	  System.exit( -1 );
	}
      }

      l.clear();

      if ( l.removeTail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.removeFront() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "11" ) ) {

      System.out.println( "TestList 11: Test unlink/head");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      if ( l.removeTail() != null ) {
	System.out.println("Test failed: removeTail() != null ");
	System.exit( -1 );
      }

      if ( l.removeFront() != null ) {
	System.out.println("Test failed: removeFront() != null ");
	System.exit( -1 );
      }

      for ( int i = 0; i < names.length; i++ ) {
	TestListNode n = new TestListNode( names[ i ] );
	l.addToTail( n );

	if ( n != (TestListNode) l.tail() ) {
	  System.out.println("Test failed: Unexpected tail ");
	  System.exit( -1 );
	}
      }

      System.out.println( "Removing Mickey" );

      ListNode n = l.front();
      
      while ( n != l.head() ) {
	TestListNode t = (TestListNode) n;
	if ( t.name().equals("Mickey") ) {
	  t.unlink();
	  if ( t.getPrevious() != t.getNext() ) {
	    System.out.println("Test failed: previous!= next in unlinked node ");
	    System.exit( -1 );
	  }
	  break;
	}
	n = n.getNext();
      }

      System.out.println( "Removing Donald" );

      n = l.front();
      while ( n != l.head() ) {
	TestListNode t = (TestListNode) n;
	if ( t.name().equals("Donald") ) {
	  t.unlink();
	  if ( t.getPrevious() != t.getNext() ) {
	    System.out.println("Test failed: previous!= next in unlinked node ");
	    System.exit( -1 );
	  }
	  break;
	}
	n = n.getNext();
      }

      System.out.println( "Test if either Mickey or Donald exist" );

      n = l.front();
      while ( n != l.head() ) {
	TestListNode t = (TestListNode) n;
	if ( t.name().equals("Donald") || t.name().equals("Mickey") ) {
	  System.out.println("Test failed: found Donald or Mickey");
	  System.exit( -1 );
	}

	n = n.getNext();
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "12" ) ) {

      System.out.println( "TestList 12: Test forwardIterator");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      // iterate over names
      int i = 0;
      ListForwardIterator iterator = new ListForwardIterator( l );

      while ( iterator.hasMoreNodes() ) {
	TestListNode t = (TestListNode) iterator.nextNode();
	System.out.println( "Get:" + t.name() );
	if ( !names[ i ].equals( t.name() ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
	i++;
      }

      if ( i != names.length ) {
	  System.out.println("Test failed: i=" + i );
	  System.exit( -1 );
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "13" ) ) {

      System.out.println( "TestList 13: Test backwardIterator");
      List l = new List();

      String [] names = { "Mickey", "Mimi", "Donald", "Dumbo", "Snow White" };

      for ( int i = 0; i < names.length; i++ ) {
	l.addToTail( new TestListNode( names[ i ] ) );
      }

      // iterate over names
      int i = names.length-1;
      ListBackwardIterator iterator = new ListBackwardIterator( l );

      while ( iterator.hasMoreNodes() ) {
	TestListNode t = (TestListNode) iterator.nextNode();
	System.out.println( "Get:" + t.name() );
	if ( !names[ i ].equals( t.name() ) ) {
	  System.out.println("Test failed: Expected " + names[ i ] );
	  System.exit( -1 );
	}
	i--;
      }

      if ( i != -1 ) {
	  System.out.println("Test failed: i=" + i );
	  System.exit( -1 );
      }

      System.out.println("Test passed");
    }
    else if ( args[ 0 ].equals( "14" ) ) {

      System.out.println( "TestList 14: Test append");
      List l1 = new List();
      List l2 = new List();

      String [] names1 = { "Mickey", "Mimi", "Donald" };
      String [] names2 = { "Dumbo", "Snow White" };

      for ( int i = 0; i < names1.length; i++ ) {
	l1.addToTail( new TestListNode( names1[ i ] ) );
      }

      for ( int i = 0; i < names2.length; i++ ) {
	l2.addToTail( new TestListNode( names2[ i ] ) );
      }

      // Append l2 to l1
      l1.append( l2 );

      for ( int i = 0; i < names1.length; i++ ) {
	TestListNode n = (TestListNode) l1.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names1[i] ) ) {
	  System.out.println("Test failed: Expected " + names1[ i ] );
	  System.exit( -1 );
	}
      }

      for ( int i = 0; i < names2.length; i++ ) {
	TestListNode n = (TestListNode) l1.removeFront();
	System.out.println( "Get:" + n.name() );
	if ( !n.name().equals( names2[i] ) ) {
	  System.out.println("Test failed: Expected " + names2[ i ] );
	  System.exit( -1 );
	}
      }

      if ( ! l2.isEmpty() ) {
	System.out.println("Test failed: l2 is not empty");
      }

      System.out.println("Test passed");
    }
    else {
      System.out.println( usage() );
    }

  }
}
