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

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

public class SynchronizedBooleanTests extends TestCase {
	private volatile SynchronizedBoolean sb;
	private volatile boolean exCaught;
	private volatile boolean timeoutOccurred;
	private volatile long startTime;
	private volatile long endTime;


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

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		this.sb = new SynchronizedBoolean();
		this.exCaught = false;
		this.timeoutOccurred = false;
		this.startTime = 0;
		this.endTime = 0;
	}

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

	public void testGetValue() throws Exception {
		assertFalse(this.sb.getValue());
	}

	public void testIs() throws Exception {
		assertTrue(this.sb.is(false));
	}

	public void testIsNot() throws Exception {
		assertTrue(this.sb.isNot(true));
	}

	public void testIsTrue() throws Exception {
		assertFalse(this.sb.isTrue());
	}

	public void testIsFalse() throws Exception {
		assertTrue(this.sb.isFalse());
	}

	public void testSetValueFalse() throws Exception {
		this.sb.setValue(false);
		assertFalse(this.sb.getValue());
		assertFalse(this.sb.isTrue());
		assertTrue(this.sb.isFalse());
	}

	public void testSetValueTrue() throws Exception {
		this.sb.setValue(true);
		assertTrue(this.sb.getValue());
		assertTrue(this.sb.isTrue());
		assertFalse(this.sb.isFalse());
	}

	public void testFlip() throws Exception {
		assertTrue(this.sb.flip());
		assertFalse(this.sb.flip());
	}

	public void testSetNotTrue() throws Exception {
		this.sb.setNot(true);
		assertFalse(this.sb.getValue());
		assertFalse(this.sb.isTrue());
		assertTrue(this.sb.isFalse());
	}

	public void testSetNotFalse() throws Exception {
		this.sb.setNot(false);
		assertTrue(this.sb.getValue());
		assertTrue(this.sb.isTrue());
		assertFalse(this.sb.isFalse());
	}

	public void testSetFalse() throws Exception {
		this.sb.setFalse();
		assertFalse(this.sb.getValue());
		assertFalse(this.sb.isTrue());
		assertTrue(this.sb.isFalse());
	}

	public void testSetTrue() throws Exception {
		this.sb.setTrue();
		assertTrue(this.sb.getValue());
		assertTrue(this.sb.isTrue());
		assertFalse(this.sb.isFalse());
	}

	public void testGetMutexThis() throws Exception {
		assertSame(this.sb, this.sb.getMutex());
	}

	public void testGetMutexObject() throws Exception {
		Object mutex = new Object();
		SynchronizedBoolean syncBool = new SynchronizedBoolean(mutex);
		assertSame(mutex, syncBool.getMutex());
	}

	public void testEquals() throws Exception {
		this.sb.setValue(false);
		SynchronizedBoolean sb2 = new SynchronizedBoolean(false);
		assertEquals(this.sb, sb2);

		this.sb.setValue(true);
		assertFalse(this.sb.equals(sb2));

		sb2.setValue(true);
		assertEquals(this.sb, sb2);
	}

	public void testHashCode() {
		this.sb.setValue(false);
		assertEquals(0, this.sb.hashCode());

		this.sb.setValue(true);
		assertEquals(1, this.sb.hashCode());
	}

	public void testWaitUntilTrue() throws Exception {
		this.verifyWaitUntilTrue(0);
		// no timeout occurs...
		assertFalse(this.timeoutOccurred);
		// ...and the value should be set to true by t2
		assertTrue(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.elapsedTime() > 150);
	}

	public void testWaitUntilTrueTimeout() throws Exception {
		this.verifyWaitUntilTrue(20);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to true by t1
		assertTrue(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.elapsedTime() < 150);
	}

	private void verifyWaitUntilTrue(long timeout) throws Exception {
		this.sb.setFalse();
		Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
		Runnable r2 = this.buildRunnable(this.buildWaitUntilTrueCommand(timeout), this.sb, 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);
	}

	public void testWaitToSetFalse() throws Exception {
		this.verifyWaitToSetFalse(0);
		// no timeout occurs...
		assertFalse(this.timeoutOccurred);
		// ...and the value should be set to false by t2
		assertFalse(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.elapsedTime() > 150);
	}

	public void testWaitToSetFalseTimeout() throws Exception {
		this.verifyWaitToSetFalse(20);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to true by t1
		assertTrue(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.elapsedTime() < 150);
	}

	private void verifyWaitToSetFalse(long timeout) throws Exception {
		this.sb.setFalse();
		Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
		Runnable r2 = this.buildRunnable(this.buildWaitToSetFalseCommand(timeout), this.sb, 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 buildSetTrueCommand() {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) {
				syncBool.setTrue();
			}
		};
	}

	private Command buildWaitUntilTrueCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws Exception {
				SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
				SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitUntilTrue(timeout));
				SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
			}
		};
	}

	private Command buildWaitToSetFalseCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws Exception {
				SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
				SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitToSetFalse(timeout));
				SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
			}
		};
	}

	private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long sleep) {
		return new Runnable() {
			public void run() {
				try {
					if (sleep != 0) {
						Thread.sleep(sleep);
					}
					command.execute(syncBool);
				} catch (Exception ex) {
					SynchronizedBooleanTests.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;
	}

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


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

	private interface Command {
		void execute(SynchronizedBoolean syncBool) throws Exception;
	}

}
