import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.junit.AfterClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class Testing {
	
	private static int points = 0;
	
	
	@Test
	public void testAdd(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertTrue(l.add(1));
		for (int i = 2; i < 100; i++) assertTrue(l.add(i));
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.add(i);
		assertEquals(1000000, l.size());
		points += 10;
	}
	
	@Test
	public void testAddLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		l.addLast(1);
		for (int i = 2; i < 100; i++) l.addLast(i);
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.addLast(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testOffer(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertTrue(l.offer(1));
		for (int i = 2; i < 100; i++) assertTrue(l.offer(i));
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.offer(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testOfferLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertTrue(l.offerLast(1));
		for (int i = 2; i < 100; i++) assertTrue(l.offerLast(i));
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.offerLast(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testAddFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		l.addFirst(1);
		for (int i = 2; i < 100; i++) l.addFirst(i);
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.addFirst(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testPush(){
		DoublyLinkedList l = new DoublyLinkedList();
		l.push(1);
		for (int i = 2; i < 100; i++) l.push(i);
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.push(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testOfferFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertTrue(l.offerFirst(1));
		for (int i = 2; i < 100; i++) assertTrue(l.offerFirst(i));
		l = new DoublyLinkedList();
		for (int i = 0; i < 1000000; i++) l.offerFirst(i);
		assertEquals(1000000, l.size());
		points += 1;
	}
	
	@Test
	public void testSize(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(0, l.size());
		for (int i = 1; i < 100; i++) {
			l.add(i);
			assertEquals(i, l.size());
		}
		for (int i = 99; i > 0; i--) {
			assertEquals(i, l.size());
			l.remove();
		}
		points += 5;
	}
	
	@Test
	public void testClear(){
		DoublyLinkedList l = new DoublyLinkedList();
		l.add(1);
		assertEquals(1, l.size());
		l.clear();
		assertEquals(0, l.size());
		for (int i = 1; i < 50; i++) {
			l.add(i);
			assertEquals(i, l.size());
		}
		l.clear();
		assertEquals(0, l.size());
		for (int i = 50; i < 100; i++) {
			l.add(i);
			assertEquals(i-49, l.size());
		}
		l.clear();
		assertEquals(0, l.size());
		points += 2;
	}
	
	@Test
	public void testElement(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.element();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		for (int i = 1; i < 100; i++) {
			l.addFirst(i);
			assertEquals(new Integer(i), l.element());
		}
		assertEquals(99, l.size());
		l.clear();
		try {
			l.element();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 2;
	}
	
	@Test
	public void testGetFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.getFirst();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		for (int i = 1; i < 100; i++) {
			l.addFirst(i);
			assertEquals(new Integer(i), l.getFirst());
		}
		assertEquals(99, l.size());
		l.clear();
		try {
			l.getFirst();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 1;
	}
	
	@Test
	public void testPeek(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.peek());
		for (int i = 1; i < 100; i++) {
			l.addFirst(i);
			assertEquals(new Integer(i), l.peek());
		}
		assertEquals(99, l.size());
		l.clear();
		assertEquals(null, l.peek());
		points += 2;
	}
	
	@Test
	public void testPeekFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.peekFirst());
		for (int i = 1; i < 100; i++) {
			l.addFirst(i);
			assertEquals(new Integer(i), l.peekFirst());
		}
		assertEquals(99, l.size());
		l.clear();
		assertEquals(null, l.peekFirst());
		points += 1;
	}

	@Test
	public void testGetLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.getLast();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		for (int i = 1; i < 100; i++) {
			l.add(i);
			assertEquals(new Integer(i), l.getLast());
		}
		assertEquals(99, l.size());
		l.clear();
		try {
			l.getLast();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 2;
	}
	
	@Test
	public void testPeekLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.peekLast());
		for (int i = 1; i < 100; i++) {
			l.add(i); 
			assertEquals(new Integer(i), l.peekLast());
		}
		assertEquals(99, l.size());
		l.clear();
		assertEquals(null, l.peekLast());
		points += 2;
	}
	
	@Test
	public void testPoll(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.poll());
		l.add(42);
		assertEquals(new Integer(42), l.poll());
		assertEquals(0, l.size());
		assertEquals(null, l.poll());
		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 1; i < 100; i++) {
			assertEquals(new Integer(i), l.poll()); 
		}
		assertEquals(0, l.size());
		points += 5;
	}
	
	@Test
	public void testPollFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.pollFirst());
		l.add(42);
		assertEquals(new Integer(42), l.pollFirst());
		assertEquals(0, l.size());
		assertEquals(null, l.pollFirst());
		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 1; i < 100; i++) {
			assertEquals(new Integer(i), l.pollFirst()); 
		}
		assertEquals(0, l.size());
		points += 1;
	}

	@Test
	public void testRemove(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.remove();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		l.add(42);
		assertEquals(new Integer(42), l.remove());
		assertEquals(0, l.size());
		try {
			l.remove();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 1; i < 100; i++) {
			assertEquals(new Integer(i), l.remove()); 
		}
		assertEquals(0, l.size());
		try {
			l.remove();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 2;
	}
	
	@Test
	public void testPop(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.pop();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		l.add(42);
		assertEquals(new Integer(42), l.pop());
		assertEquals(0, l.size());
		try {
			l.pop();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 1; i < 100; i++) {
			assertEquals(new Integer(i), l.pop()); 
		}
		assertEquals(0, l.size());
		try {
			l.pop();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 1;
	}
	
	@Test
	public void testRemoveFirst(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.removeFirst();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		l.add(42);
		assertEquals(new Integer(42), l.removeFirst());
		assertEquals(0, l.size());
		try {
			l.removeFirst();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 1; i < 100; i++) {
			assertEquals(new Integer(i), l.removeFirst()); 
		}
		assertEquals(0, l.size());
		try {
			l.removeFirst();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 1;
	}
	
	@Test
	public void testPollLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		assertEquals(null, l.pollLast());
		l.add(42);
		assertEquals(new Integer(42), l.pollLast());
		assertEquals(0, l.size());
		assertEquals(null, l.pollLast());
		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 99; i >= 1; i--) {
			assertEquals(new Integer(i), l.pollLast()); 
		}
		assertEquals(0, l.size());
		assertEquals(null, l.pollLast());
		points += 5;
	}
	
	@Test
	public void testRemoveLast(){
		DoublyLinkedList l = new DoublyLinkedList();
		try {
			l.removeLast();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		l.add(42);
		assertEquals(new Integer(42), l.removeLast());
		assertEquals(0, l.size());
		try {
			l.removeLast();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		
		for (int i = 1; i < 100; i++) {
			l.add(i); 
		}
		assertEquals(99, l.size());
		for (int i = 99; i >= 1; i--) {
			assertEquals(new Integer(i), l.removeLast()); 
		}
		assertEquals(0, l.size());
		try {
			l.removeLast();
			fail("Did not throw NoSuchElementException");
		} catch (Exception e){
			if (!(e instanceof NoSuchElementException)) {
				fail("Did not throw NoSuchElementException");				
			}
		}
		points += 2;
	}
	
	@AfterClass
	public static void testDoNothing(){
		System.out.println("Points: " + points);
	}	
	
}