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

import java.util.Vector;
import org.eclipse.jpt.common.utility.command.Command;
import org.eclipse.jpt.common.utility.internal.CompositeException;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.SynchronizedObject;
import org.eclipse.jpt.common.utility.synchronizers.Synchronizer;

/**
 * This synchronizer will synchronize immediately and not return until the
 * synchronization and any nested (recursive) synchronizations are complete.
 * In some situations this implementation should be used sparingly, and for as
 * short a time as possible, as it increases the probability of deadlocks. A
 * deadlock can occur when {@link Synchronizer#synchronize()} is called from multiple
 * threads and multiple resources are locked by the synchronization in varying
 * orders.
 * <p>
 * As defined in the {@link Synchronizer} interface, {@link Synchronizer#start()}
 * and {@link Synchronizer#stop()}
 * should be called in the same thread, but it is not required.
 * {@link Synchronizer#synchronize()} should
 * always be called in the same thread (i.e. only recursively, beyond the
 * initial call); although, this too is not required.
 * This thread need not be the same thread that executes
 * {@link Synchronizer#start()} and {@link Synchronizer#stop()}.
 */
public class SynchronousSynchronizer
	implements Synchronizer
{
	/**
	 * The client-supplied command that performs the synchronization. It may
	 * trigger further calls to {@link #synchronize()} (i.e. the
	 * synchronization may recurse).
	 */
	private final Command command;

	/**
	 * The synchronizer's current state.
	 */
	final SynchronizedObject<State> state;

	/**
	 * The synchronizer's initial state is {@link #STOPPED}.
	 */
	enum State {
		STOPPED,
		READY,
		EXECUTING,
		REPEAT,
		STOPPING
	}

	/**
	 * A list of the uncaught exceptions thrown by the command.
	 */
	final Vector<Throwable> exceptions = new Vector<Throwable>();


	// ********** construction **********

	/**
	 * Construct a synchronous synchronizer that uses the specified command to
	 * perform the synchronization.
	 */
	public SynchronousSynchronizer(Command command) {
		super();
		if (command == null) {
			throw new NullPointerException();
		}
		this.command = command;
		// use the synchronizer as the mutex so it is freed up by the wait in #stop()
		this.state = new SynchronizedObject<State>(State.STOPPED, this);
	}


	// ********** Synchronizer implementation **********

	/**
	 * Set the synchronizer's {@link #state} to {@link State#READY READY}
	 * and execute the first synchronization. Throw an exception if the
	 * synchronizer is not {@link State#STOPPED STOPPED}.
	 */
	public synchronized void start() {
		switch (this.state.getValue()) {
			case STOPPED:
				this.state.setValue(State.READY);
				this.synchronize();
				break;
			case READY:
			case EXECUTING:
			case REPEAT:
			case STOPPING:
				throw this.buildISE();
		}
	}

	/**
	 * It's possible to come back here if the synchronization command recurses
	 * and triggers another synchronization.
	 */
	public void synchronize() {
		if (this.beginSynchronization()) {
			this.synchronize_();
		}
	}

	/**
	 * A client has requested a synchronization.
	 * Return whether we can begin a new synchronization.
	 * If a synchronization is already under way, return <code>false</code>;
	 * but set the {@link #state} to {@link State#REPEAT REPEAT}
	 * so another synchronization will occur once the current
	 * synchronization is complete.
	 */
	private synchronized boolean beginSynchronization() {
		switch (this.state.getValue()) {
			case STOPPED:
				// synchronization is not allowed
				return false;
			case READY:
				// begin a new synchronization
				this.state.setValue(State.EXECUTING);
				return true;
			case EXECUTING:
				// set flag so a new synchronization will occur once the current one is finished
				this.state.setValue(State.REPEAT);
				return false;
			case REPEAT:
				// the "repeat" flag is already set
				return false;
			case STOPPING:
				// no further synchronizations are allowed
				return false;
		}
		throw this.buildISE();
	}

	/**
	 * This method should be called only once per set of "recursing"
	 * synchronizations. Any recursive call to {@link #synchronize()} will
	 * simply set the {@link #state} to {@link State#REPEAT REPEAT},
	 * causing the command to execute again.
	 */
	private void synchronize_() {
		do {
			this.execute();
		} while (this.repeatSynchronization());
	}

	/**
	 * Execute the client-supplied command. Do not allow any unhandled
	 * exceptions to kill the thread. Store them up for later pain.
	 */
	private void execute() {
		try {
			this.execute_();
		} catch (Throwable ex) {
			this.exceptions.add(ex);
		}
	}

	/**
	 * By default, just execute the command.
	 */
	void execute_() {
		this.command.execute();
	}

	/**
	 * The current synchronization has finished.
	 * Return whether we should begin another synchronization.
	 */
	private synchronized boolean repeatSynchronization() {
		switch (this.state.getValue()) {
			case STOPPED:
			case READY:
				throw this.buildISE();
			case EXECUTING:
				// synchronization has finished and there are no outstanding requests for another; return to "ready"
				this.state.setValue(State.READY);
				return false;
			case REPEAT:
				// the "repeat" flag was set; clear it and start another synchronization
				this.state.setValue(State.EXECUTING);
				return true;
			case STOPPING:
				// a client has initiated a "stop"; mark the "stop" complete and perform no more synchronizations
				this.state.setValue(State.STOPPED);
				return false;
		}
		throw this.buildISE();
	}

	/**
	 * Set the flags so that no further synchronizations occur. If any uncaught
	 * exceptions were thrown while the synchronization was executing,
	 * wrap them in a composite exception and throw the composite exception.
	 */
	public synchronized void stop() {
		switch (this.state.getValue()) {
			case STOPPED:
				throw this.buildISE();
			case READY:
				// simply return to "stopped" state
				this.state.setValue(State.STOPPED);
				break;
			case EXECUTING:
			case REPEAT:
				// set the "stopping" flag and wait until the synchronization has finished
				this.state.setValue(State.STOPPING);
				this.waitUntilStopped();
				break;
			case STOPPING:
				throw this.buildISE();
		}

		if (this.exceptions.size() > 0) {
			Throwable[] temp = this.exceptions.toArray(new Throwable[this.exceptions.size()]);
			this.exceptions.clear();
			throw new CompositeException(temp);
		}
	}

	/**
	 * This wait will free up the synchronizer's synchronized methods
	 * (since the synchronizer is the state's mutex).
	 */
	private void waitUntilStopped() {
		try {
			this.state.waitUntilValueIs(State.STOPPED);
		} catch (InterruptedException ex) {
			// the thread that called #stop() was interrupted while waiting
			// for the synchronization to finish - ignore;
			// 'state' is still set to 'STOPPING', so the #synchronize_() loop
			// will still stop - we just won't wait around for it...
		}
	}

	private IllegalStateException buildISE() {
		return new IllegalStateException("state: " + this.state); //$NON-NLS-1$
	}

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.state);
	}
}
