/*******************************************************************************
 * Copyright (c) 2005 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.tests.navigator;

import java.util.logging.Level;
import java.util.logging.Logger;

import junit.framework.Assert;

import org.eclipse.swt.widgets.Display;

/**
 * Implements the thread that will wait for the timeout and wake up the display
 * so it does not wait forever. The thread may be restarted after it was stopped
 * or timed out.
 * 
 * @since 3.1
 */
final class DisplayWaiter {
	/**
	 * Timeout state of a display waiter thread.
	 */
	public final class Timeout {
		boolean fTimeoutState= false;
		/**
		 * Returns <code>true</code> if the timeout has been reached,
		 * <code>false</code> if not.
		 * 
		 * @return <code>true</code> if the timeout has been reached,
		 *         <code>false</code> if not
		 */
		public boolean hasTimedOut() {
			synchronized (fMutex) {
				return fTimeoutState;
			}
		}
		void setTimedOut(boolean timedOut) {
			fTimeoutState= timedOut;
		}
		Timeout(boolean initialState) {
			fTimeoutState= initialState;
		}
	}
	
	// configuration
	private final Display fDisplay;
	private final Object fMutex= new Object();
	private final boolean fKeepRunningOnTimeout;
	
	/* State -- possible transitions:
	 * 
	 * STOPPED   -> RUNNING
	 * RUNNING   -> STOPPED
	 * RUNNING   -> IDLE
	 * IDLE      -> RUNNING
	 * IDLE      -> STOPPED
	 */
	private static final int RUNNING= 1 << 1;
	private static final int STOPPED= 1 << 2;
	private static final int IDLE= 1 << 3;
	
	/** The current state. */
	private int fState;
	/** The time in milliseconds (see Date) that the timeout will occur. */
	private long fNextTimeout;
	/** The thread. */
	private Thread fCurrentThread;
	/** The timeout state of the current thread. */
	private Timeout fCurrentTimeoutState;

	/**
	 * Creates a new instance on the given display and timeout.
	 * 
	 * @param display the display to run the event loop of
	 */
	public DisplayWaiter(Display display) {
		this(display, false);
	}
	
	/**
	 * Creates a new instance on the given display and timeout.
	 * 
	 * @param display the display to run the event loop of
	 * @param keepRunning <code>true</code> if the thread should be kept
	 *        running after timing out
	 */
	public DisplayWaiter(Display display, boolean keepRunning) {
		Assert.assertNotNull(display);
		fDisplay= display;
		fState= STOPPED;
		fKeepRunningOnTimeout= keepRunning;
	}
	
	/**
	 * Starts the timeout thread if it is not currently running. Nothing happens
	 * if a thread is already running.
	 * 
	 * @param delay the delay from now in milliseconds
	 * @return the timeout state which can be queried for its timed out status
	 */
	public Timeout start(long delay) {
		Assert.assertTrue(delay > 0);
		synchronized (fMutex) {
			switch (fState) {
				case STOPPED:
					startThread();
					setNextTimeout(delay);
					break;
				case IDLE:
					unhold();
					setNextTimeout(delay);
					break;
			}
			
			return fCurrentTimeoutState;
		}
	}

	/**
	 * Sets the next timeout to <em>current time</em> plus <code>delay</code>.
	 * 
	 * @param delay the delay until the next timeout occurs in milliseconds from
	 *        now
	 */
	private void setNextTimeout(long delay) {
		long currentTimeMillis= System.currentTimeMillis();
		long next= currentTimeMillis + delay;
		if (next > currentTimeMillis)
			fNextTimeout= next;
		else
			fNextTimeout= Long.MAX_VALUE;
	}
	
	/**
	 * Starts the thread if it is not currently running; resets the timeout if
	 * it is.
	 * 
	 * @param delay the delay from now in milliseconds
	 * @return the timeout state which can be queried for its timed out status
	 */
	public Timeout restart(long delay) {
		Assert.assertTrue(delay > 0);
		synchronized (fMutex) {
			switch (fState) {
				case STOPPED:
					startThread();
					break;
				case IDLE:
					unhold();
					break;
			}
			setNextTimeout(delay);

			return fCurrentTimeoutState;
		}
	}

	/**
	 * Stops the thread if it is running. If not, nothing happens. Another
	 * thread may be started by calling {@link #start(long)} or
	 * {@link #restart(long)}.
	 */
	public void stop() {
		synchronized (fMutex) {
			if (tryTransition(RUNNING | IDLE, STOPPED))
				fMutex.notifyAll();
		}
	}
	
	/**
	 * Puts the reaper thread on hold but does not stop it. It may be restarted
	 * by calling {@link #start(long)} or {@link #restart(long)}.
	 */
	public void hold() {
		synchronized (fMutex) {
			// nothing to do if there is no thread
			if (tryTransition(RUNNING, IDLE))
				fMutex.notifyAll();
		}
	}

	/**
	 * Transition to <code>RUNNING</code> and clear the timed out flag. Assume
	 * current state is <code>IDLE</code>.
	 */
	private void unhold() {
		checkedTransition(IDLE, RUNNING);
		fCurrentTimeoutState= new Timeout(false);
		fMutex.notifyAll();
	}
		
	/**
	 * Start the thread. Assume the current state is <code>STOPPED</code>.
	 */
	private void startThread() {
		checkedTransition(STOPPED, RUNNING);
		fCurrentTimeoutState= new Timeout(false);
		fCurrentThread= new Thread() {
			/**
			 * Exception thrown when a thread notices that it has been stopped
			 * and a new thread has been started.
			 */
			final class ThreadChangedException extends Exception {
				private static final long serialVersionUID= 1L;
			}

			/*
			 * @see java.lang.Runnable#run()
			 */
			public void run() {
				try {
					run2();
				} catch (InterruptedException e) {
					// ignore and end the thread - we never interrupt ourselves,
					// so it must be an external entity that interrupted us
					Logger.global.log(Level.FINE, "", e); //$NON-NLS-1$
				} catch (ThreadChangedException e) {
					// the thread was stopped and restarted before we got out
					// of a wait - we're no longer used
					// we might have been notified instead of the current thread,
					// so wake it up
					Logger.global.log(Level.FINE, "", e); //$NON-NLS-1$
					synchronized (fMutex) {
						fMutex.notifyAll();
					}
				}
			}
			
			/**
			 * Runs the thread.
			 * 
			 * @throws InterruptedException if the thread was interrupted
			 * @throws ThreadChangedException if the thread changed
			 */
			private void run2() throws InterruptedException, ThreadChangedException {
				synchronized (fMutex) {
					checkThread();
					tryHold(); // wait / potential state change
					assertStates(STOPPED | RUNNING);
					
					while (isState(RUNNING)) {
						waitForTimeout(); // wait / potential state change
						
						if (isState(RUNNING))
							timedOut(); // state change
						assertStates(STOPPED | IDLE);
						
						tryHold(); // wait / potential state change
						assertStates(STOPPED | RUNNING);
					}
					assertStates(STOPPED);
				}
			}

			/**
			 * Check whether the current thread is this thread, throw an
			 * exception otherwise.
			 * 
			 * @throws ThreadChangedException if the current thread changed
			 */
			private void checkThread() throws ThreadChangedException {
				if (fCurrentThread != this)
					throw new ThreadChangedException();
			}

			/**
			 * Waits until the next timeout occurs.
			 * 
			 * @throws InterruptedException if the thread was interrupted
			 * @throws ThreadChangedException if the thread changed
			 */
			private void waitForTimeout() throws InterruptedException, ThreadChangedException {
				long delta;
				while (isState(RUNNING) && (delta = fNextTimeout - System.currentTimeMillis()) > 0) {
					delta= Math.max(delta, 50); // wait at least 50ms in order to avoid timing out before the display is going to sleep
					Logger.global.finest("sleeping for " + delta + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
					fMutex.wait(delta);
					checkThread();
				}
			}

			/**
			 * Sets the timed out flag and wakes up the display. Transitions to
			 * <code>IDLE</code> (if in keep-running mode) or
			 * <code>STOPPED</code>.
			 */
			private void timedOut() {
				Logger.global.finer("timed out"); //$NON-NLS-1$
				fCurrentTimeoutState.setTimedOut(true);
				fDisplay.wake(); // wake up call!
				if (fKeepRunningOnTimeout)
					checkedTransition(RUNNING, IDLE);
				else
					checkedTransition(RUNNING, STOPPED);
			}
			
			/**
			 * Waits while the state is <code>IDLE</code>, then returns. The
			 * state must not be <code>RUNNING</code> when calling this
			 * method. The state is either <code>STOPPED</code> or
			 * <code>RUNNING</code> when the method returns.
			 * 
			 * @throws InterruptedException if the thread was interrupted
			 * @throws ThreadChangedException if the thread has changed while on
			 *         hold
			 */
			private void tryHold() throws InterruptedException, ThreadChangedException {
				while (isState(IDLE)) {
					fMutex.wait(0);
					checkThread();
				}
				assertStates(STOPPED | RUNNING);
			}
		};
		
		fCurrentThread.start();
	}
	
	/**
	 * Transitions to <code>nextState</code> if the current state is one of
	 * <code>possibleStates</code>. Returns <code>true</code> if the
	 * transition happened, <code>false</code> otherwise.
	 * 
	 * @param possibleStates the states which trigger a transition
	 * @param nextState the state to transition to
	 * @return <code>true</code> if the transition happened,
	 *         <code>false</code> otherwise
	 */
	private boolean tryTransition(int possibleStates, int nextState) {
		if (isState(possibleStates)) {
			Logger.global.finer(name(fState) + " > " + name(nextState) + " (" + name(possibleStates) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			fState= nextState;
			return true;
		}
		Logger.global.finest("noTransition" + name(fState) + " !> " + name(nextState) + " (" + name(possibleStates) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		return false;
	}
	
	/**
	 * Checks the <code>possibleStates</code> and throws an assertion if it is
	 * not met, then transitions to <code>nextState</code>.
	 * 
	 * @param possibleStates the allowed states
	 * @param nextState the state to transition to
	 */
	private void checkedTransition(int possibleStates, int nextState) {
		assertStates(possibleStates);
		Logger.global.finer(name(fState) + " > " + name(nextState)); //$NON-NLS-1$
		fState= nextState;
	}
	
	/**
	 * Implements state consistency checking.
	 * 
	 * @param states the allowed states
	 * @throws junit.framework.AssertionFailedError if the current state is not
	 *         in <code>states</code>
	 */
	private void assertStates(int states) {
		Assert.assertTrue("illegal state", isState(states)); //$NON-NLS-1$
	}

	/**
	 * Answers <code>true</code> if the current state is in the given
	 * <code>states</code>.
	 * 
	 * @param states the possible states
	 * @return <code>true</code> if the current state is in the given states,
	 *         <code>false</code> otherwise
	 */
	private boolean isState(int states) {
		return (states & fState) == fState;
	}
	
	/**
	 * Pretty print the given states.
	 * 
	 * @param states the states
	 * @return a string representation of the states
	 */
	private String name(int states) {
		StringBuffer buf= new StringBuffer();
		boolean comma= false;
		if ((states & RUNNING) == RUNNING) {
			buf.append("RUNNING"); //$NON-NLS-1$
			comma= true;
		}
		if ((states & STOPPED) == STOPPED) {
			if (comma)
				buf.append(","); //$NON-NLS-1$
			buf.append("STOPPED"); //$NON-NLS-1$
			comma= true;
		}
		if ((states & IDLE) == IDLE) {
			if (comma)
				buf.append(","); //$NON-NLS-1$
			buf.append("IDLE"); //$NON-NLS-1$
		}
		return buf.toString();
	}

}