/*******************************************************************************
 * Copyright (c) 2005, 2009 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.tests.internal.iterators;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import junit.framework.TestCase;
import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
import org.eclipse.jpt.utility.tests.internal.TestTools;

@SuppressWarnings("nls")
public class CloneListIteratorTests extends TestCase {
	List<String> originalList;

	private boolean concurrentProblem;
	private List<String> concurrentList;

	public CloneListIteratorTests(String name) {
		super(name);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.originalList = this.buildList();
	}

	@Override
	protected void tearDown() throws Exception {
		TestTools.clear(this);
		super.tearDown();
	}

	public void testHasNext() {
		int originalSize = this.originalList.size();
		int i = 0;
		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
			stream.next();
			// should allow concurrent modification
			this.originalList.add("foo");
			i++;
		}
		assertTrue(originalSize != this.originalList.size());
		assertEquals(originalSize, i);
	}

	public void testNext() {
		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
			assertEquals("bogus element", nestedListIterator.next(), stream.next());
		}
	}

	public void testIndex() {
		ListIterator<String> cloneListIterator = this.buildCloneListIterator();
		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
		for (int i = 0; i < 7; i++) {
			nestedListIterator.next();
			cloneListIterator.next();
			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
		}

		for (int i = 0; i < 3; i++) {
			nestedListIterator.previous();
			cloneListIterator.previous();
			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
		}

		while (nestedListIterator.hasNext()) {
			nestedListIterator.next();
			cloneListIterator.next();
			assertEquals("bogus index", nestedListIterator.nextIndex(), cloneListIterator.nextIndex());
			assertEquals("bogus index", nestedListIterator.previousIndex(), cloneListIterator.previousIndex());
		}
	}

	public void testHasPrevious() {
		int originalSize = this.originalList.size();
		int i = 0;
		ListIterator<String> stream = this.buildCloneListIterator();
		while (stream.hasNext()) {
			stream.next();
			this.originalList.add("foo");
			i++;
		}
		assertTrue(originalSize != this.originalList.size());
		originalSize = this.originalList.size();
		while (stream.hasPrevious()) {
			stream.previous();
			// should allow concurrent modification
			this.originalList.add("bar");
			i--;
		}
		assertTrue(originalSize != this.originalList.size());
		assertEquals(0, i);
	}

	public void testPrevious() {
		ListIterator<String> nestedListIterator = this.buildNestedListIterator();
		ListIterator<String> stream = this.buildCloneListIterator();
		while (stream.hasNext()) {
			nestedListIterator.next();
			stream.next();
		}
		while (stream.hasPrevious()) {
			assertEquals("bogus element", nestedListIterator.previous(), stream.previous());
		}
	}

	public void testNoSuchElementException() {
		boolean exCaught = false;
		ListIterator<String> stream = this.buildCloneListIterator();
		String string = null;
		while (stream.hasNext()) {
			string = stream.next();
		}
		try {
			string = stream.next();
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue("NoSuchElementException not thrown: " + string, exCaught);

		exCaught = false;
		while (stream.hasPrevious()) {
			string = stream.previous();
		}
		try {
			string = stream.previous();
		} catch (NoSuchElementException ex) {
			exCaught = true;
		}
		assertTrue("NoSuchElementException not thrown: " + string, exCaught);
	}

	public void testModifyDefault() {
		boolean exCaught = false;
		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
			if (stream.next().equals("three")) {
				try {
					stream.remove();
				} catch (UnsupportedOperationException ex) {
					exCaught = true;
				}
			}
		}
		assertTrue("UnsupportedOperationException not thrown", exCaught);

		exCaught = false;
		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
			if (stream.next().equals("three")) {
				try {
					stream.add("three and a half");
				} catch (UnsupportedOperationException ex) {
					exCaught = true;
				}
			}
		}
		assertTrue("UnsupportedOperationException not thrown", exCaught);

		exCaught = false;
		for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
			if (stream.next().equals("three")) {
				try {
					stream.set("another three");
				} catch (UnsupportedOperationException ex) {
					exCaught = true;
				}
			}
		}
		assertTrue("UnsupportedOperationException not thrown", exCaught);
	}

	public void testModifyMutatorNext() {
		this.verifyModifyNext(new CloneListIterator<String>(this.originalList, this.buildMutator()));
	}

	public void testModifyMutatorPrevious() {
		this.verifyModifyPrevious(new CloneListIterator<String>(this.originalList, this.buildMutator()));
	}

	private CloneListIterator.Mutator<String> buildMutator() {
		return new CloneListIterator.Mutator<String>() {
			public void add(int index, String o) {
				CloneListIteratorTests.this.originalList.add(index, o);
			}

			public void remove(int index) {
				CloneListIteratorTests.this.originalList.remove(index);
			}

			public void set(int index, String o) {
				CloneListIteratorTests.this.originalList.set(index, o);
			}
		};
	}

	public void testModifySubclassNext() {
		this.verifyModifyNext(this.buildSubclass());
	}

	public void testModifySubclassPrevious() {
		this.verifyModifyPrevious(this.buildSubclass());
	}

	private ListIterator<String> buildSubclass() {
		return new CloneListIterator<String>(this.originalList) {
			@Override
			protected void add(int currentIndex, String o) {
				CloneListIteratorTests.this.originalList.add(currentIndex, o);
			}

			@Override
			protected void remove(int currentIndex) {
				CloneListIteratorTests.this.originalList.remove(currentIndex);
			}

			@Override
			protected void set(int currentIndex, String o) {
				CloneListIteratorTests.this.originalList.set(currentIndex, o);
			}
		};
	}

	private void verifyModifyNext(ListIterator<String> iterator) {
		String removed = "three";
		String addedAfter = "five";
		String added = "five and a half";
		String replaced = "seven";
		String replacement = "another seven";
		assertTrue(this.originalList.contains(removed));
		assertTrue(this.originalList.contains(addedAfter));
		assertTrue(this.originalList.contains(replaced));
		// try to remove before calling #next()
		boolean exCaught = false;
		try {
			iterator.remove();
		} catch (IllegalStateException ex) {
			exCaught = true;
		}
		assertTrue(exCaught);
		while (iterator.hasNext()) {
			String next = iterator.next();
			if (next.equals(addedAfter)) {
				iterator.add(added);
			}
			if (next.equals(removed)) {
				iterator.remove();
				// try to remove twice
				exCaught = false;
				try {
					iterator.remove();
				} catch (IllegalStateException ex) {
					exCaught = true;
				}
				assertTrue(exCaught);
			}
			if (next.equals(replaced)) {
				iterator.set(replacement);
			}
		}
		assertTrue(this.originalList.contains(added));
		assertFalse(this.originalList.contains(removed));
		assertFalse(this.originalList.contains(replaced));
		assertTrue(this.originalList.contains(replacement));
	}

	private void verifyModifyPrevious(ListIterator<String> iterator) {
		String removed = "three";
		String addedBefore = "five";
		String added = "four and a half";
		String replaced = "seven";
		String replacement = "another seven";
		assertTrue(this.originalList.contains(removed));
		assertTrue(this.originalList.contains(addedBefore));
		assertTrue(this.originalList.contains(replaced));
		while (iterator.hasNext()) {
			iterator.next();
		}
		while (iterator.hasPrevious()) {
			Object previous = iterator.previous();
			if (previous.equals(addedBefore)) {
				iterator.add(added);
			}
			if (previous.equals(removed)) {
				iterator.remove();
				// try to remove twice
				boolean exCaught = false;
				try {
					iterator.remove();
				} catch (IllegalStateException ex) {
					exCaught = true;
				}
				assertTrue("IllegalStateException not thrown", exCaught);
			}
			if (previous.equals(replaced)) {
				iterator.set(replacement);
			}
		}
		assertTrue(this.originalList.contains(added));
		assertFalse(this.originalList.contains(removed));
		assertFalse(this.originalList.contains(replaced));
		assertTrue(this.originalList.contains(replacement));
	}

	private ListIterator<String> buildCloneListIterator() {
		return this.buildCloneListIterator(this.originalList);
	}

	private ListIterator<String> buildCloneListIterator(List<String> list) {
		return new CloneListIterator<String>(list);
	}

	private ListIterator<String> buildNestedListIterator() {
		return this.originalList.listIterator();
	}

	private List<String> buildList() {
		List<String> list = this.buildEmptyList();
		this.populateList(list);
		return list;
	}

	private void populateList(List<String> list) {
		list.add("zero");
		list.add("one");
		list.add("two");
		list.add("three");
		list.add("four");
		list.add("five");
		list.add("six");
		list.add("seven");
		list.add("eight");
		list.add("nine");
	}

	protected List<String> buildEmptyList() {
		return new ArrayList<String>();
	}

	/**
	 * Test concurrent access: First build a clone iterator in a separate thread
	 * that hangs momentarily during its construction; then modify the shared
	 * collection in this thread. This would cause a
	 * ConcurrentModificationException in the other thread if the clone iterator
	 * were not synchronized on the original collection.
	 */
	public void testConcurrentAccess() throws Exception {
		CloneIteratorTests.SlowCollection<String> slow = new CloneIteratorTests.SlowCollection<String>();
		this.populateList(slow);
		// using the unsynchronized list will cause the test to fail
		// this.originalList = slow;
		this.originalList = Collections.synchronizedList(slow);

		this.concurrentProblem = false;
		this.concurrentList = new ArrayList<String>();
		Thread thread = new Thread(this.buildRunnable());
		thread.start();
		while (!slow.hasStartedClone()) {
			// wait for the other thread to start the clone...
			Thread.yield();
		}
		// ...then sneak in an extra element
		this.originalList.add("seventeen");
		while (thread.isAlive()) {
			// wait for the other thread to finish
			Thread.yield();
		}
		assertFalse(this.concurrentProblem);
		List<String> expected = new ArrayList<String>();
		this.populateList(expected);
		assertEquals(expected, this.concurrentList);
	}

	private Runnable buildRunnable() {
		return new Runnable() {
			public void run() {
				CloneListIteratorTests.this.loopWithCloneListIterator();
			}
		};
	}

	/**
	 * use a clone iterator to loop over the "slow" collection and copy its
	 * contents to the concurrent collection
	 */
	void loopWithCloneListIterator() {
		try {
			for (ListIterator<String> stream = this.buildCloneListIterator(); stream.hasNext();) {
				this.concurrentList.add(stream.next());
			}
		} catch (Throwable t) {
			this.concurrentProblem = true;
		}
	}

}
