/*******************************************************************************
 * Copyright (c) 2007, 2012 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.common.utility.internal;

import java.io.Serializable;
import org.eclipse.jpt.common.utility.command.InterruptibleCommand;
import org.eclipse.jpt.common.utility.command.InterruptibleCommandExecutor;

/**
 * This class provides synchronized access to a <code>boolean</code> value.
 * It also provides protocol for suspending a thread until the
 * <code>boolean</code> value is set to <code>true</code> or <code>false</code>,
 * with optional time-outs.
 * 
 * @see SimpleBooleanReference
 */
public class SynchronizedBoolean
	implements InterruptibleCommandExecutor, ModifiableBooleanReference, Cloneable, Serializable
{
	/** Backing <code>boolean</code>. */
	private boolean value;

	/** Object to synchronize on. */
	private final Object mutex;

	private static final long serialVersionUID = 1L;


	// ********** constructors **********

	/**
	 * Create a synchronized <code>boolean</code> with the specified
	 * initial value and mutex.
	 */
	public SynchronizedBoolean(boolean value, Object mutex) {
		super();
		this.value = value;
		this.mutex = mutex;
	}

	/**
	 * Create a synchronized <code>boolean</code> with the
	 * specified initial value.
	 * The synchronized <code>boolean</code> itself will be the mutex.
	 */
	public SynchronizedBoolean(boolean value) {
		super();
		this.value = value;
		this.mutex = this;
	}

	/**
	 * Create a synchronized <code>boolean</code>
	 * with an initial value of <code>false</code>
	 * and specified mutex.
	 */
	public SynchronizedBoolean(Object mutex) {
		this(false, mutex);
	}

	/**
	 * Create a synchronized <code>boolean</code>
	 * with an initial value of <code>false</code>.
	 * The synchronized <code>boolean</code> itself will be the mutex.
	 */
	public SynchronizedBoolean() {
		this(false);
	}


	// ********** accessors **********

	public boolean getValue() {
		synchronized (this.mutex) {
			return this.value;
		}
	}

	public boolean is(boolean b) {
		synchronized (this.mutex) {
			return this.value == b;
		}
	}

	public boolean isNot(boolean b) {
		synchronized (this.mutex) {
			return this.value != b;
		}
	}

	public boolean isTrue() {
		synchronized (this.mutex) {
			return this.value;
		}
	}

	public boolean isFalse() {
		synchronized (this.mutex) {
			return ! this.value;
		}
	}

	/**
	 * If the value changes, all waiting threads are notified.
	 * Return the <em>old</em> value.
	 */
	public boolean setValue(boolean value) {
		synchronized (this.mutex) {
			return (value == this.value) ? value : ! this.setChangedValue_(value);
		}
	}

	/**
	 * Pre-condition: synchronized; new value is different
	 * <br>
	 * Return the <em>new</em> value.
	 */
	private boolean setChangedValue_(boolean v) {
		this.value = v;
		this.mutex.notifyAll();
		return v;
	}

	/**
	 * If the value changes, all waiting threads are notified.
	 * Return the new value.
	 */
	public boolean flip() {
		synchronized (this.mutex) {
			return this.setChangedValue_( ! this.value);
		}
	}

	/**
	 * Set the value to <code>value & b</code> and return the new value.
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean and(boolean b) {
		synchronized (this.mutex) {
			return this.setValue_(this.value & b);
		}
	}

	/**
	 * Set the value to <code>value | b</code> and return the new value.
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean or(boolean b) {
		synchronized (this.mutex) {
			return this.setValue_(this.value | b);
		}
	}

	/**
	 * Set the value to <code>value ^ b</code> and return the new value.
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean xor(boolean b) {
		synchronized (this.mutex) {
			return this.setValue_(this.value ^ b);
		}
	}

	/**
	 * Pre-condition: synchronized
	 * <br>
	 * Return the <em>new</em> value.
	 */
	private boolean setValue_(boolean v) {
		return (v == this.value) ? v : this.setChangedValue_(v);
	}

	/**
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean setNot(boolean b) {
		return this.setValue( ! b);
	}

	/**
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean setTrue() {
		return this.setValue(true);
	}

	/**
	 * If the value changes, all waiting threads are notified.
	 */
	public boolean setFalse() {
		return this.setValue(false);
	}

	/**
	 * Set the value to the specified new value if it is currently the specified
	 * expected value. If the value changes, all waiting threads are notified.
	 * Return whether the commit was successful.
	 */
	public boolean commit(boolean expectedValue, boolean newValue) {
		synchronized (this.mutex) {
			boolean success = (this.value == expectedValue);
			if (success) {
				this.setValue_(newValue);
			}
			return success;
		}
	}

	/**
	 * Atomically swap the value of this synchronized boolean with the value of
	 * the specified synchronized boolean. Make assumptions about the value of
	 * <em>identity hash code</em> to avoid deadlock when two synchronized
	 * booleans swap values with each other simultaneously.
	 * If either value changes, the corresponding waiting threads are notified.
	 * Return the new value.
	 */
	public boolean swap(SynchronizedBoolean other) {
		if (other == this) {
			return this.getValue();
		}
		boolean thisFirst = System.identityHashCode(this) < System.identityHashCode(other);
		SynchronizedBoolean first = thisFirst ? this : other;
		SynchronizedBoolean second = thisFirst ? other : this;
		synchronized (first.mutex) {
			synchronized (second.mutex) {
				boolean thisValue = this.value;
				boolean otherValue = other.value;
				if (thisValue == otherValue) {
					return thisValue;  // nothing changes
				}
				other.setChangedValue_(thisValue);
				return this.setChangedValue_(otherValue);
			}
		}
	}

	/**
	 * Return the object this object locks on while performing
	 * its operations.
	 */
	public Object getMutex() {
		return this.mutex;
	}


	// ********** indefinite waits **********

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to the specified value. If the <code>boolean</code> value is already the
	 * specified value, return immediately.
	 */
	public void waitUntilValueIs(boolean b) throws InterruptedException {
		synchronized (this.mutex) {
			this.waitUntilValueIs_(b);
		}
	}

	/**
	 * Pre-condition: synchronized
	 */
	private void waitUntilValueIs_(boolean b) throws InterruptedException {
		while (this.value != b) {
			this.mutex.wait();
		}
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to the NOT of the specified value.
	 * If the <code>boolean</code> value is already the NOT of the specified
	 * value, return immediately.
	 */
	public void waitUntilValueIsNot(boolean b) throws InterruptedException {
		this.waitUntilValueIs( ! b);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>true</code>.
	 * If the <code>boolean</code> value is already <code>true</code>,
	 * return immediately.
	 */
	public void waitUntilTrue() throws InterruptedException {
		this.waitUntilValueIs(true);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>false</code>.
	 * If the <code>boolean</code> value is already <code>false</code>,
	 * return immediately.
	 */
	public void waitUntilFalse() throws InterruptedException {
		this.waitUntilValueIs(false);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes to
	 * the NOT of the specified value, then change it back to the specified
	 * value and continue executing. If the <code>boolean</code> value is already
	 * the NOT of the specified value, set the value to the specified value
	 * immediately.
	 */
	public void waitToSetValue(boolean b) throws InterruptedException {
		synchronized (this.mutex) {
			this.waitUntilValueIs_( ! b);
			this.setChangedValue_(b);
		}
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>false</code>,
	 * then change it back to <code>true</code> and continue executing.
	 * If the <code>boolean</code> value is already <code>false</code>,
	 * set the value to <code>true</code> immediately.
	 */
	public void waitToSetTrue() throws InterruptedException {
		this.waitToSetValue(true);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>true</code>,
	 * then change it back to <code>false</code> and continue executing.
	 * If the <code>boolean</code> value is already <code>true</code>,
	 * set the value to <code>false</code> immediately.
	 */
	public void waitToSetFalse() throws InterruptedException {
		this.waitToSetValue(false);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to the specified value,
	 * then execute the specified command.
	 * If the <code>boolean</code> value is already equal to the specified
	 * value, execute the specified command immediately.
	 */
	public void whenEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
		synchronized (this.mutex) {
			this.waitUntilValueIs_(b);
			command.execute();
		}
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to the NOT of the specified value,
	 * then execute the specified command.
	 * If the <code>boolean</code> value is already the NOT of the specified
	 * value, execute the specified command immediately.
	 */
	public void whenNotEqual(boolean b, InterruptibleCommand command) throws InterruptedException {
		this.whenEqual( ! b, command);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>true</code>,
	 * then execute the specified command.
	 * If the <code>boolean</code> value is already <code>true</code>,
	 * execute the specified command immediately.
	 */
	public void whenTrue(InterruptibleCommand command) throws InterruptedException {
		this.whenEqual(true, command);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to <code>false</code>,
	 * then execute the specified command.
	 * If the <code>boolean</code> value is already <code>false</code>,
	 * execute the specified command immediately.
	 */
	public void whenFalse(InterruptibleCommand command) throws InterruptedException {
		this.whenEqual(false, command);
	}


	// ********** timed waits **********

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to the specified value or the specified time-out occurs.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the specified value was achieved;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already the specified value,
	 * return <code>true</code> immediately.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitUntilValueIs(boolean b, long timeout) throws InterruptedException {
		synchronized (this.mutex) {
			return this.waitUntilValueIs_(b, timeout);
		}
	}

	/**
	 * Pre-condition: synchronized
	 */
	private boolean waitUntilValueIs_(boolean b, long timeout) throws InterruptedException {
		if (timeout == 0L) {
			this.waitUntilValueIs_(b);	// wait indefinitely until notified
			return true;	// if it ever comes back, the condition was met
		}

		long stop = System.currentTimeMillis() + timeout;
		long remaining = timeout;
		while ((this.value != b) && (remaining > 0L)) {
			this.mutex.wait(remaining);
			remaining = stop - System.currentTimeMillis();
		}
		return (this.value == b);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value
	 * changes to the NOT of the specified value or the specified time-out occurs.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the NOT of the specified value was achieved;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already the NOT of the specified
	 * value, return <code>true</code> immediately.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitUntilValueIsNot(boolean b, long timeout) throws InterruptedException {
		return this.waitUntilValueIs( ! b, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>true</code> or the specified time-out occurs.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * <code>true</code> was achieved;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>true</code>,
	 * return <code>true</code> immediately.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitUntilTrue(long timeout) throws InterruptedException {
		return this.waitUntilValueIs(true, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>false</code> or the specified time-out occurs.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * <code>false</code> was achieved;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>false</code>,
	 * return <code>true</code> immediately.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitUntilFalse(long timeout) throws InterruptedException {
		return this.waitUntilValueIs(false, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to the NOT of the specified value, then change it back to the specified
	 * value and continue executing. If the <code>boolean</code> value does not
	 * change to <code>false</code> before the time-out, simply continue
	 * executing without changing the value.
	 * The time-out is specified in milliseconds. Return <code>true</code>
	 * if the value was set to the specified value; return <code>false</code>
	 * if a time-out occurred.
	 * If the <code>boolean</code> value is already
	 * the NOT of the specified value, set the value to the specified value
	 * immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitToSetValue(boolean b, long timeout) throws InterruptedException {
		synchronized (this.mutex) {
			boolean success = this.waitUntilValueIs_( ! b, timeout);
			if (success) {
				this.setChangedValue_(b);
			}
			return success;
		}
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>false</code>, then change it back to <code>true</code> and
	 * continue executing. If the <code>boolean</code> value does not change to
	 * <code>false</code> before the time-out, simply continue executing without
	 * changing the value. 
	 * The time-out is specified in milliseconds. Return
	 * <code>true</code> if the value was set to <code>true</code>;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>false</code>, set the
	 * value to <code>true</code> immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitToSetTrue(long timeout) throws InterruptedException {
		return this.waitToSetValue(true, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>true</code>, then change it back to <code>false</code> and
	 * continue executing. If the <code>boolean</code> value does not change to
	 * <code>true</code> before the time-out, simply continue executing without
	 * changing the value.
	 * The time-out is specified in milliseconds. Return
	 * <code>true</code> if the value was set to <code>false</code>;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>true</code>, set the
	 * value to <code>false</code> immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean waitToSetFalse(long timeout) throws InterruptedException {
		return this.waitToSetValue(false, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to the specified value or the specified time-out occurs;
	 * then, if a time-out did not occur, execute the specified command.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the command was executed;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already the specified value,
	 * execute the specified command immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean whenEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
		synchronized (this.mutex) {
			boolean success = this.waitUntilValueIs_(b, timeout);
			if (success) {
				command.execute();
			}
			return success;
		}
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to the NOT of the specified value or the specified time-out occurs;
	 * then, if a time-out did not occur, execute the specified command.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the command was executed;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already the NOT of the specified value,
	 * execute the specified command immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean whenNotEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException {
		return this.whenEqual( ! b, command, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>true</code> or the specified time-out occurs;
	 * then, if a time-out did not occur, execute the specified command.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the command was executed;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>true</code>,
	 * execute the specified command immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean whenTrue(InterruptibleCommand command, long timeout) throws InterruptedException {
		return this.whenEqual(true, command, timeout);
	}

	/**
	 * Suspend the current thread until the <code>boolean</code> value changes
	 * to <code>false</code> or the specified time-out occurs;
	 * then, if a time-out did not occur, execute the specified command.
	 * The time-out is specified in milliseconds. Return <code>true</code> if
	 * the command was executed;
	 * return <code>false</code> if a time-out occurred.
	 * If the <code>boolean</code> value is already <code>false</code>,
	 * execute the specified command immediately and return <code>true</code>.
	 * If the time-out is zero, wait indefinitely.
	 */
	public boolean whenFalse(InterruptibleCommand command, long timeout) throws InterruptedException {
		return this.whenEqual(false, command, timeout);
	}


	// ********** synchronized behavior **********

	/**
	 * If the current thread is not interrupted, execute the specified command 
	 * with the mutex locked. This is useful for initializing the value from another
	 * thread.
	 */
	public void execute(InterruptibleCommand command) throws InterruptedException {
		if (Thread.currentThread().isInterrupted()) {
			throw new InterruptedException();
		}
		synchronized (this.mutex) {
			command.execute();
		}
	}


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

	@Override
	public SynchronizedBoolean clone() {
		try {
			synchronized (this.mutex) {
				return (SynchronizedBoolean) super.clone();
			}
		} catch (CloneNotSupportedException ex) {
			throw new InternalError();
		}
	}

	/**
	 * Object identity is critical to synchronized booleans.
	 * There is no reason for two different synchronized booleans to be
	 * <em>equal</em>.
	 */
	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}

	/**
	 * @see #equals(Object)
	 */
	@Override
	public int hashCode() {
		return super.hashCode();
	}

	@Override
	public String toString() {
		return '[' + String.valueOf(this.getValue()) + ']';
	}

	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
		synchronized (this.mutex) {
			s.defaultWriteObject();
		}
	}
}
