/*******************************************************************************
 * Copyright (c) 2007, 2008 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;

import junit.framework.TestCase;
import org.eclipse.jpt.utility.internal.SynchronizedObject;

public class SynchronizedObjectTests extends TestCase {
	private volatile SynchronizedObject<Object> so;
	private volatile boolean exCaught;
	private volatile boolean timeoutOccurred;
	volatile Object value = new Object();
	private volatile long startTime;
	private volatile long endTime;
	private volatile Object soValue;


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

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.so = new SynchronizedObject<Object>();
		this.exCaught = false;
		this.timeoutOccurred = false;
		this.startTime = 0;
		this.endTime = 0;
		this.soValue = null;
	}

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

	public void testAccessors() throws Exception {
		this.so.setValue(null);
		assertNull(this.so.value());
		assertFalse(this.so.isNotNull());
		assertTrue(this.so.isNull());

		this.so.setValue(this.value);
		assertEquals(this.value, this.so.value());
		assertTrue(this.so.isNotNull());
		assertFalse(this.so.isNull());

		this.so.setNull();
		assertNull(this.so.value());
		assertFalse(this.so.isNotNull());
		assertTrue(this.so.isNull());

		assertSame(this.so, this.so.mutex());
	}

	public void testEquals() throws Exception {
		this.so.setValue(null);
		SynchronizedObject<Object> so2 = new SynchronizedObject<Object>(null);
		assertEquals(this.so, so2);

		this.so.setValue(this.value);
		assertFalse(this.so.equals(so2));

		so2.setValue(this.value);
		assertEquals(this.so, so2);
	}

	public void testHashCode() {
		this.so.setValue(this.value);
		assertEquals(this.value.hashCode(), this.so.hashCode());

		this.so.setValue(null);
		assertEquals(0, this.so.hashCode());
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to null
	 */
	public void testWaitUntilNull() throws Exception {
		this.verifyWaitUntilNull(0);
		// no timeout occurs...
		assertFalse(this.timeoutOccurred);
		// ...and the value should be set to null by t2
		assertNull(this.so.value());
		// make a reasonable guess about how long t2 took
		long time = this.elapsedTime();
		assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to null
	 */
	public void testWaitUntilNullTimeout() throws Exception {
		this.verifyWaitUntilNull(20);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to null by t1
		assertNull(this.so.value());
		// make a reasonable guess about how long t2 took
		long time = this.elapsedTime();
		assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
	}

	private void verifyWaitUntilNull(long t2Timeout) throws Exception {
		this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout));
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to null;
	 * then t2 will set the value to an object
	 */
	public void testWaitToSetValue() throws Exception {
		this.verifyWaitToSetValue(0);
		// no timeout occurs...
		assertFalse(this.timeoutOccurred);
		// ...and the value should be set to an object by t2
		assertTrue(this.so.isNotNull());
		// make a reasonable guess about how long t2 took
		long time = this.elapsedTime();
		assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to null
	 */
	public void testWaitToSetValueTimeout() throws Exception {
		this.verifyWaitToSetValue(20);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to null by t1
		assertTrue(this.so.isNull());
		// make a reasonable guess about how long t2 took
		long time = this.elapsedTime();
		assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
	}

	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
		this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout));
	}

	/**
	 * t2 will wait until t1 is finished "initializing" the value;
	 * then t2 will get the newly-initialized value ("foo")
	 */
	public void testExecute() throws Exception {
		this.so.setValue(null);
		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0);
		// give t1 a head start of 100 ms
		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, 100);
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {
			Thread.sleep(50);
		}
		assertFalse(this.exCaught);
		assertEquals("foo", this.so.value());
		assertEquals("foo", this.soValue);
		// make a reasonable guess about how long t2 took
		long time = this.elapsedTime();
		assertTrue("t2 finished a bit early (expected value should be > 100): " + time, time > 300);
	}

	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
		this.so.setValue(this.value);
		Runnable r1 = this.buildRunnable(t1Command, this.so, 200);
		Runnable r2 = this.buildRunnable(t2Command, this.so, 0);
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {
			Thread.sleep(50);
		}
		assertFalse(this.exCaught);
	}

	private Command buildSetNullCommand() {
		return new Command() {
			public void execute(SynchronizedObject<Object> sObject) {
				sObject.setNull();
			}
		};
	}

	private Command buildWaitUntilNullCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedObject<Object> sObject) throws Exception {
				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
				SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitUntilNull(timeout));
				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
			}
		};
	}

	private Command buildWaitToSetValueCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedObject<Object> sObject) throws Exception {
				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
				SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout));
				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
			}
		};
	}

	private Command buildInitializeValueCommand() {
		return new Command() {
			public void execute(final SynchronizedObject<Object> sObject) throws Exception {
				sObject.execute(
					new org.eclipse.jpt.utility.Command() {
						public void execute() {
							// pretend to perform some long initialization process
							try {
								Thread.sleep(500);
							} catch (Exception ex) {
								SynchronizedObjectTests.this.setExCaught(true);
							}
							sObject.setValue("foo");
						}
					}
				);
			}
		};
	}

	private Command buildGetValueCommand() {
		return new Command() {
			public void execute(SynchronizedObject<Object> sObject) throws Exception {
				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
				SynchronizedObjectTests.this.setSOValue(sObject.value());
				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
			}
		};
	}

	private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) {
		return new Runnable() {
			public void run() {
				try {
					if (sleep != 0) {
						Thread.sleep(sleep);
					}
					command.execute(sObject);
				} catch (Exception ex) {
					SynchronizedObjectTests.this.setExCaught(true);
				}
			}
		};
	}

	void setExCaught(boolean exCaught) {
		this.exCaught = exCaught;
	}

	void setTimeoutOccurred(boolean timeoutOccurred) {
		this.timeoutOccurred = timeoutOccurred;
	}

	void setStartTime(long startTime) {
		this.startTime = startTime;
	}

	void setEndTime(long endTime) {
		this.endTime = endTime;
	}

	private long elapsedTime() {
		return this.endTime - this.startTime;
	}

	void setSOValue(Object soValue) {
		this.soValue = soValue;
	}


	// ********** Command interface **********

	private interface Command {
		void execute(SynchronizedObject<Object> so) throws Exception;
	}

}
