/*******************************************************************************
 * Copyright (c) 2010 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.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.SynchronizedIterator;
import org.eclipse.jpt.utility.tests.internal.MultiThreadedTestCase;
import org.eclipse.jpt.utility.tests.internal.TestTools;

@SuppressWarnings("nls")
public class SynchronizedIteratorTests
	extends MultiThreadedTestCase
{
	public SynchronizedIteratorTests(String name) {
		super(name);
	}

	/**
	 * test that an unsynchronized iterator will produce corrupt output;
	 * thread 1 will read the first element from the iterator
	 * and then sleep for a bit, allowing thread 2 to sneak in and
	 * read the same element from the iterator
	 */
	public void testUnsynchronizedNext() throws Exception {
		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		iterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		this.sleep(TICK);
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// both threads should have read the same element from the iterator :-(
		assertEquals("foo", runnable1.next);
		assertEquals("foo", runnable2.next);
	}

	/**
	 * test that a synchronized iterator will produce valid output;
	 * thread 1 will read the first element from the iterator
	 * and then sleep for a bit, but thread 2 will be locked out and
	 * wait to read the second element from the iterator
	 */
	public void testSynchronizedNext() throws Exception {
		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		NextTestRunnable<String> runnable2 = new NextTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		nestedIterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		this.sleep(TICK);
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// the threads should have read the correct elements from the iterator :-)
		assertEquals("foo", runnable1.next);
		assertEquals("bar", runnable2.next);
	}

	public void testUnsynchronizedHasNext() throws Exception {
		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
		iterator.next();
		iterator.next();

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		iterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		this.sleep(TICK);
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// thread 1 will have the last element,
		// but thread 2 will think there are more elements on the iterator :-(
		assertEquals("baz", runnable1.next);
		assertEquals(true, runnable2.hasNext);
	}

	public void testSynchronizedHasNext() throws Exception {
		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
		iterator.next();
		iterator.next();

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		HasNextTestRunnable<String> runnable2 = new HasNextTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		nestedIterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		this.sleep(TICK);
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// thread 1 will have the last element,
		// and thread 2 will think there are no more elements on the iterator :-)
		assertEquals("baz", runnable1.next);
		assertEquals(false, runnable2.hasNext);
	}

	public void testUnsynchronizedRemove() throws Exception {
		TestIterator<String> iterator = this.buildTestIterator(TWO_TICKS);
		iterator.next();

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		iterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// the wrong element was removed :-(
		assertEquals("bar", runnable1.next);
		assertFalse(iterator.list.contains("foo"));
		assertTrue(iterator.list.contains("bar"));
		assertTrue(iterator.list.contains("baz"));
	}

	public void testSynchronizedRemove() throws Exception {
		TestIterator<String> nestedIterator = this.buildTestIterator(TWO_TICKS);
		Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
		iterator.next();

		NextTestRunnable<String> runnable1 = new NextTestRunnable<String>(iterator);
		Thread thread1 = this.buildThread(runnable1);
		RemoveTestRunnable<String> runnable2 = new RemoveTestRunnable<String>(iterator);
		Thread thread2 = this.buildThread(runnable2);
		nestedIterator.slowThread = thread1;

		thread1.start();

		// allow thread 1 to read the first element and get bogged down
		this.sleep(TICK);
		thread2.start();

		// wait for the threads to finish
		thread1.join();
		thread2.join();

		// the correct element was removed :-)
		assertEquals("bar", runnable1.next);
		assertTrue(nestedIterator.list.contains("foo"));
		assertFalse(nestedIterator.list.contains("bar"));
		assertTrue(nestedIterator.list.contains("baz"));
	}

	TestIterator<String> buildTestIterator(long delay) {
		return new TestIterator<String>(delay, this.buildArray());
	}

	String[] buildArray() {
		return new String[] {"foo", "bar", "baz"};
	}

	Iterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
		return new SynchronizedIterator<String>(nestedIterator);
	}


	/**
	 * next runnable
	 */
	class NextTestRunnable<E> implements Runnable {
		final Iterator<E> iterator;
		E next;

		NextTestRunnable(Iterator<E> iterator) {
			super();
			this.iterator = iterator;
		}

		public void run() {
			this.next = this.iterator.next();
		}

	}

	/**
	 * has next runnable
	 */
	class HasNextTestRunnable<E> implements Runnable {
		final Iterator<E> iterator;
		boolean hasNext;

		HasNextTestRunnable(Iterator<E> iterator) {
			super();
			this.iterator = iterator;
		}

		public void run() {
			this.hasNext = this.iterator.hasNext();
		}

	}

	/**
	 * remove runnable
	 */
	class RemoveTestRunnable<E> implements Runnable {
		final Iterator<E> iterator;

		RemoveTestRunnable(Iterator<E> iterator) {
			super();
			this.iterator = iterator;
		}

		public void run() {
			this.iterator.remove();
		}

	}

	/**
	 * Test iterator: If {@link #next()} is called while executing on the
	 * {@link slowThread}, the iterator will delay for the configured time.
	 */
	static class TestIterator<E> implements Iterator<E> {
		final long delay;
		final ArrayList<E> list = new ArrayList<E>();
		int nextIndex = 0;
		int lastIndex = -1;
		Thread slowThread;

		TestIterator(long delay, E... array) {
			super();
			this.delay = delay;
			CollectionTools.addAll(this.list, array);
		}

		public boolean hasNext() {
			return this.nextIndex != this.list.size();
		}

		public E next() {
			if (this.hasNext()) {
				E next = this.list.get(this.nextIndex);
				if (Thread.currentThread() == this.slowThread) {
					TestTools.sleep(this.delay);
				}
				this.lastIndex = this.nextIndex++;
				return next;
			}
			throw new NoSuchElementException();
		}

		public void remove() {
			if (this.lastIndex == -1) {
				throw new IllegalStateException();
			}
			this.list.remove(this.lastIndex);
			if (this.lastIndex < this.nextIndex) {  // check necessary for ListIterator
				this.nextIndex--;
			}
			this.lastIndex = -1;
		}
	}

}
