/*******************************************************************************
 * Copyright (c) 2007 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 org.eclipse.jpt.utility.internal.SynchronizedBoolean;

import junit.framework.TestCase;

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 testAccessors() throws Exception {
		this.sb.setValue(false);
		assertFalse(this.sb.value());
		assertFalse(this.sb.isTrue());
		assertTrue(this.sb.isFalse());

		this.sb.setValue(true);
		assertTrue(this.sb.value());
		assertTrue(this.sb.isTrue());
		assertFalse(this.sb.isFalse());

		this.sb.setFalse();
		assertFalse(this.sb.value());
		assertFalse(this.sb.isTrue());
		assertTrue(this.sb.isFalse());

		this.sb.setTrue();
		assertTrue(this.sb.value());
		assertTrue(this.sb.isTrue());
		assertFalse(this.sb.isFalse());

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

	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.value());
		// 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.value());
		// 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.value());
		// 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.value());
		// 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;
	}

}
