/*******************************************************************************
 * Copyright (c) 2007, 2015 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0, which accompanies this distribution
 * and is available at https://www.eclipse.org/legal/epl-2.0/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.utility.tests.internal.reference;

import org.eclipse.jpt.common.utility.internal.command.InterruptibleCommandAdapter;
import org.eclipse.jpt.common.utility.internal.reference.SimpleBooleanReference;
import org.eclipse.jpt.common.utility.internal.reference.SynchronizedBoolean;
import org.eclipse.jpt.common.utility.reference.ModifiableBooleanReference;
import org.eclipse.jpt.common.utility.tests.internal.MultiThreadedTestCase;
import org.eclipse.jpt.common.utility.tests.internal.TestTools;

@SuppressWarnings("nls")
public class SynchronizedBooleanTests
	extends MultiThreadedTestCase
{
	private volatile SynchronizedBoolean sb;
	volatile boolean timeoutOccurred;
	volatile long startTime;
	volatile long endTime;


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

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

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

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

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

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

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

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

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

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

	public void testFalseAndTrue() throws Exception {
		assertFalse(this.sb.and(true));
		assertFalse(this.sb.getValue());
	}

	public void testTrueAndTrue() throws Exception {
		this.sb.setValue(true);
		assertTrue(this.sb.and(true));
		assertTrue(this.sb.getValue());
	}

	public void testFalseAndFalse() throws Exception {
		assertFalse(this.sb.and(false));
		assertFalse(this.sb.getValue());
	}

	public void testTrueAndFalse() throws Exception {
		this.sb.setValue(true);
		assertFalse(this.sb.and(false));
		assertFalse(this.sb.getValue());
	}

	public void testFalseOrTrue() throws Exception {
		assertTrue(this.sb.or(true));
		assertTrue(this.sb.getValue());
	}

	public void testTrueOrTrue() throws Exception {
		this.sb.setValue(true);
		assertTrue(this.sb.or(true));
		assertTrue(this.sb.getValue());
	}

	public void testFalseOrFalse() throws Exception {
		assertFalse(this.sb.or(false));
		assertFalse(this.sb.getValue());
	}

	public void testTrueOrFalse() throws Exception {
		this.sb.setValue(true);
		assertTrue(this.sb.or(false));
		assertTrue(this.sb.getValue());
	}

	public void testFalseXorTrue() throws Exception {
		assertTrue(this.sb.xor(true));
		assertTrue(this.sb.getValue());
	}

	public void testTrueXorTrue() throws Exception {
		this.sb.setValue(true);
		assertFalse(this.sb.xor(true));
		assertFalse(this.sb.getValue());
	}

	public void testFalseXorFalse() throws Exception {
		assertFalse(this.sb.xor(false));
		assertFalse(this.sb.getValue());
	}

	public void testTrueXorFalse() throws Exception {
		this.sb.setValue(true);
		assertTrue(this.sb.xor(false));
		assertTrue(this.sb.getValue());
	}

	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 testCommitFalseSuccess() throws Exception {
		assertTrue(this.sb.commit(false, false));
		assertFalse(this.sb.getValue());
	}

	public void testCommitTrueSuccess() throws Exception {
		assertTrue(this.sb.commit(true, false));
		assertTrue(this.sb.getValue());
	}

	public void testCommitFalseFailure() throws Exception {
		assertFalse(this.sb.commit(false, true));
		assertFalse(this.sb.getValue());
	}

	public void testCommitTrueFailure() throws Exception {
		assertFalse(this.sb.commit(true, true));
		assertFalse(this.sb.getValue());
	}

	public void testSwapSame1() throws Exception {
		assertFalse(this.sb.swap((ModifiableBooleanReference) this.sb));
		assertFalse(this.sb.getValue());
	}

	public void testSwapSameValues1() throws Exception {
		ModifiableBooleanReference sb2 = new SimpleBooleanReference(false);
		assertFalse(this.sb.swap(sb2));
		assertFalse(this.sb.getValue());
		assertFalse(sb2.getValue());
	}

	public void testSwapDifferentValues1() throws Exception {
		ModifiableBooleanReference sb2 = new SimpleBooleanReference(true);
		assertTrue(this.sb.swap(sb2));
		assertTrue(this.sb.getValue());
		assertFalse(sb2.getValue());
	}

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

	public void testSwapSameValues2() throws Exception {
		SynchronizedBoolean sb2 = new SynchronizedBoolean();
		assertFalse(this.sb.swap(sb2));
		assertFalse(this.sb.getValue());
		assertFalse(sb2.getValue());

		assertFalse(sb2.swap(this.sb));
		assertFalse(this.sb.getValue());
		assertFalse(sb2.getValue());
	}

	public void testSwapDifferentValues2() throws Exception {
		SynchronizedBoolean sb2 = new SynchronizedBoolean(true);
		assertTrue(this.sb.swap(sb2));
		assertTrue(this.sb.getValue());
		assertFalse(sb2.getValue());

		assertTrue(sb2.swap(this.sb));
		assertFalse(this.sb.getValue());
		assertTrue(sb2.getValue());
	}

	public void testSwpSameValues3() throws Exception {
		ModifiableBooleanReference sb2 = new SynchronizedBoolean();
		assertFalse(this.sb.swap(sb2));
		assertFalse(this.sb.getValue());
		assertFalse(sb2.getValue());
	}

	public void testSwapDifferentValues3() throws Exception {
		ModifiableBooleanReference sb2 = new SynchronizedBoolean(true);
		assertTrue(this.sb.swap(sb2));
		assertTrue(this.sb.getValue());
		assertFalse(sb2.getValue());
	}

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

	/**
	 * t2 will wait indefinitely until t1 sets the value to true
	 */
	public void testWaitUntilTrue() throws Exception {
		this.verifyWaitUntilTrue(-1);  // explicit indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	public void testWaitUntilTrue2() throws Exception {
		this.verifyWaitUntilTrue(0);  // 0 = indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to true
	 */
	public void testWaitUntilTrueTimeout() throws Exception {
		this.verifyWaitUntilTrue(TICK);
		// 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.calculateElapsedTime() < THREE_TICKS);
	}

	/**
	 * t2 will NOT time out waiting for t1 to set the value to true
	 */
	public void testWaitUntilTrueTimeout2() throws Exception {
		this.verifyWaitUntilTrue(THREE_TICKS);
		// 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.calculateElapsedTime() >= TWO_TICKS);
	}

	private void verifyWaitUntilTrue(long t2Timeout) throws Exception {
		this.sb.setFalse();
		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitUntilTrueCommand(t2Timeout));
	}

	private Command buildWaitUntilTrueCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
				SynchronizedBooleanTests.this.timeoutOccurred = this.timeoutOccurred(syncBool);
				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
			}
			private boolean timeoutOccurred(SynchronizedBoolean syncBool) throws InterruptedException {
				if (timeout < 0) {
					syncBool.waitUntilTrue();
					return false;
				}
				return ! syncBool.waitUntilTrue(timeout);
			}
		};
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to false
	 */
	public void testWaitUntilFalse() throws Exception {
		this.verifyWaitUntilFalse(-1);  // explicit indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	public void testWaitUntilFalse2() throws Exception {
		this.verifyWaitUntilFalse(0);  // 0 = indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to false
	 */
	public void testWaitUntilFalseTimeout() throws Exception {
		this.verifyWaitUntilFalse(TICK);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to false by t1
		assertFalse(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
	}

	/**
	 * t2 will NOT time out waiting for t1 to set the value to false
	 */
	public void testWaitUntilFalseTimeout2() throws Exception {
		this.verifyWaitUntilFalse(THREE_TICKS);
		// 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.calculateElapsedTime() >= TWO_TICKS);
	}

	private void verifyWaitUntilFalse(long t2Timeout) throws Exception {
		this.sb.setTrue();
		this.executeThreads(this.buildSetFalseCommand(), this.buildWaitUntilFalseCommand(t2Timeout));
	}

	private Command buildWaitUntilFalseCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
				SynchronizedBooleanTests.this.timeoutOccurred = this.timeoutOccurred(syncBool);
				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
			}
			private boolean timeoutOccurred(SynchronizedBoolean syncBool) throws InterruptedException {
				if (timeout < 0) {
					syncBool.waitUntilFalse();
					return false;
				}
				return ! syncBool.waitUntilFalse(timeout);
			}
		};
	}

	public void testWaitUntilValueIsNotTrue() throws Exception {
		this.sb.waitUntilValueIsNot(true);
		assertFalse(this.sb.getValue());
	}

	public void testWaitUntilValueIsNotFalse() throws Exception {
		this.sb.setTrue();
		this.sb.waitUntilValueIsNot(false);
		assertTrue(this.sb.getValue());
	}

	public void testWaitUntilValueIsNotTrueTimeout() throws Exception {
		this.sb.waitUntilValueIsNot(true, 500);
		assertFalse(this.sb.getValue());
	}

	public void testWaitUntilValueIsNotFalseTimeout() throws Exception {
		this.sb.setTrue();
		this.sb.waitUntilValueIsNot(false, 500);
		assertTrue(this.sb.getValue());
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to true
	 */
	public void testWaitToSetTrue() throws Exception {
		this.verifyWaitToSetTrue(-1);  // explicit indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to true
	 */
	public void testWaitToSetTrue2() throws Exception {
		this.verifyWaitToSetTrue(0);  // 0 = indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to true
	 */
	public void testWaitToSetTrueTimeout() throws Exception {
		this.verifyWaitToSetTrue(TICK);
		// timeout occurs...
		assertTrue(this.timeoutOccurred);
		// ...and the value will eventually be set to false by t1
		assertFalse(this.sb.getValue());
		// make a reasonable guess about how long t2 took
		assertTrue(this.calculateElapsedTime() < THREE_TICKS);
	}

	/**
	 * t2 will NOT time out waiting for t1 to set the value to true
	 */
	public void testWaitToSetTrueTimeout2() throws Exception {
		this.verifyWaitUntilTrue(THREE_TICKS);
		// 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.calculateElapsedTime() >= TWO_TICKS);
	}

	private void verifyWaitToSetTrue(long t2Timeout) throws Exception {
		this.sb.setTrue();
		this.executeThreads(this.buildSetFalseCommand(), this.buildWaitToSetTrueCommand(t2Timeout));
	}

	private Command buildWaitToSetTrueCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
				SynchronizedBooleanTests.this.timeoutOccurred = this.timeoutOccurred( syncBool);
				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
			}
			private boolean timeoutOccurred(SynchronizedBoolean syncBool) throws InterruptedException {
				if (timeout < 0) {
					syncBool.waitToSetTrue();
					return false;
				}
				return ! syncBool.waitToSetTrue(timeout);
			}
		};
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to false
	 */
	public void testWaitToSetFalse() throws Exception {
		this.verifyWaitToSetFalse(-1);  // explicit indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will wait indefinitely until t1 sets the value to false
	 */
	public void testWaitToSetFalse2() throws Exception {
		this.verifyWaitToSetFalse(0);  // 0 = indefinite wait
		// 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.calculateElapsedTime() > TICK);
	}

	/**
	 * t2 will time out waiting for t1 to set the value to false
	 */
	public void testWaitToSetFalseTimeout() throws Exception {
		this.verifyWaitToSetFalse(TICK);
		// 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.calculateElapsedTime() < THREE_TICKS);
	}

	/**
	 * t2 will NOT time out waiting for t1 to set the value to false
	 */
	public void testWaitToSetFalseTimeout2() throws Exception {
		this.verifyWaitUntilFalse(THREE_TICKS);
		// 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.calculateElapsedTime() >= TWO_TICKS);
	}

	private void verifyWaitToSetFalse(long t2Timeout) throws Exception {
		this.sb.setFalse();
		this.executeThreads(this.buildSetTrueCommand(), this.buildWaitToSetFalseCommand(t2Timeout));
	}

	private Command buildWaitToSetFalseCommand(final long timeout) {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) throws InterruptedException {
				SynchronizedBooleanTests.this.startTime = System.currentTimeMillis();
				SynchronizedBooleanTests.this.timeoutOccurred = this.timeoutOccurred( syncBool);
				SynchronizedBooleanTests.this.endTime = System.currentTimeMillis();
			}
			private boolean timeoutOccurred(SynchronizedBoolean syncBool) throws InterruptedException {
				if (timeout < 0) {
					syncBool.waitToSetFalse();
					return false;
				}
				return ! syncBool.waitToSetFalse(timeout);
			}
		};
	}

	public void testWaitToSetValueNotTrue() throws Exception {
		this.sb.waitToSetValueNot(false);
		assertTrue(this.sb.getValue());
	}

	public void testWaitToSetValueNotFalse() throws Exception {
		this.sb.setTrue();
		this.sb.waitToSetValueNot(true);
		assertFalse(this.sb.getValue());
	}

	public void testWaitToSetValueNotTrueTimeout() throws Exception {
		this.sb.waitToSetValueNot(false, 500);
		assertTrue(this.sb.getValue());
	}

	public void testWaitToSetValueNotFalseTimeout() throws Exception {
		this.sb.setTrue();
		this.sb.waitToSetValueNot(true, 500);
		assertFalse(this.sb.getValue());
	}

	public void testExecute() throws Exception {
		final ModifiableBooleanReference done = new SimpleBooleanReference(false);
		this.sb.execute(new InterruptibleCommandAdapter() {
			@Override
			public void execute() throws InterruptedException {
				done.setTrue();
			}
		});
		assertTrue(done.getValue());
	}

	public void testSerialization() throws Exception {
		this.sb.setTrue();
		SynchronizedBoolean clone = TestTools.serialize(this.sb);
		assertNotSame(this.sb, clone);
		assertTrue(clone.getValue());
	}

	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
		Runnable r1 = this.buildRunnable(t1Command, this.sb, TWO_TICKS);
		Runnable r2 = this.buildRunnable(t2Command, this.sb, 0);
		Thread t1 = this.buildThread(r1);
		Thread t2 = this.buildThread(r2);
		t1.start();
		t2.start();
		t1.join();
		t2.join();
	}

	private Command buildSetTrueCommand() {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) {
				syncBool.setTrue();
			}
		};
	}

	private Command buildSetFalseCommand() {
		return new Command() {
			public void execute(SynchronizedBoolean syncBool) {
				syncBool.setFalse();
			}
		};
	}

	private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long delay) {
		return new TestRunnable() {
			@Override
			public void run_() throws InterruptedException {
				if (delay != 0) {
					Thread.sleep(delay);
				}
				command.execute(syncBool);
			}
		};
	}

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


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

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


	// ********** standard methods **********

	public void testEquals() {
		SynchronizedBoolean sb2 = new SynchronizedBoolean(true);
		assertTrue(this.sb.equals(this.sb));
		assertFalse(this.sb.equals(sb2));
	}

	public void testHashCode() {
		assertEquals(this.sb.hashCode(), this.sb.hashCode());
	}

	public void testClone() {
		SynchronizedBoolean clone = this.sb.clone();
		assertFalse(clone.getValue());
		assertNotSame(clone, this.sb);
	}

	public void testToString() {
		assertEquals("[false]", this.sb.toString());
		assertFalse(this.sb.setTrue());
		assertEquals("[true]", this.sb.toString());
	}
}
