package org.eclipse.jdt.internal.debug.eval.ast.engine;

/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp. and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.html

Contributors:
    IBM Corporation - Initial implementation
**********************************************************************/

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ITerminate;
import org.eclipse.jdt.core.dom.Message;
import org.eclipse.jdt.debug.core.IEvaluationRunnable;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.eval.ICompiledExpression;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.eval.EvaluationResult;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstructionSequence;
import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstructionsEvaluationMessages;

/**
 * An evaluation thread is a reusable object which
 * can perform a series of evaluations in a single thread.
 */
class EvaluationThread {
	private boolean fEvaluating = false;
	private Thread fEvaluationThread;
	private boolean fStopped = false;
	private Object fLock = new Object();
	private ASTEvaluationEngine fEngine;
	private Interpreter fInterpreter;
	/**
	 * Evaluation variables
	 */
	private ICompiledExpression fExpression;
	private IRuntimeContext fContext;
	private IJavaThread fThread;
	private IEvaluationListener fListener;
	private int fEvaluationDetail;
	private boolean fHitBreakpoints;
	private CoreException fException;

	/**
	 * Creates a new evaluation thread for the given
	 * evaluation engine. The engine will be notified
	 * whenever this evaluation thread completes an
	 * evaluation.
	 */
	public EvaluationThread(ASTEvaluationEngine engine) {
		fEngine = engine;
	}

	/**
	 * Returns whether this evaluation thread is currently
	 * performing an evaluation.
	 */
	public boolean isEvaluating() {
		return fEvaluating;
	}

	/**
	 * Stops any ongoing evaluations and allows
	 * the underlying thread to terminate. This method
	 * prevents the evaluation thread from reusing the
	 * underlying thread.
	 */
	public void stop() {
		fStopped = true;
		if (fInterpreter != null) {
			fInterpreter.stop();
		}
		synchronized (fLock) {
			fLock.notify();
		}
	}
	
	/**
	 * Forcibly kills the underlying evaluation thread.
	 * This method will cause any current evaluations to
	 * be terminated with an InterruptedException.
	 */
	public void kill() {
		fStopped= true;
		fEvaluationThread.interrupt();
	}

	/**
	 * Perform an evaluation. If an underlying thread already exists, the
	 * evalution thread will be carried out in that thread. Otherwise,
	 * a new thread will be created for the evaluation.
	 */
	public void evaluate(ICompiledExpression expression, IRuntimeContext context, IJavaThread thread, IEvaluationListener listener, int evaluationDetail, boolean hitBreakpoints) {
		fExpression = expression;
		fContext = context;
		fThread = thread;
		fListener = listener;
		fEvaluationDetail = evaluationDetail;
		fHitBreakpoints = hitBreakpoints;
		fException= null;
		if (fEvaluationThread == null) {
			// Create a new thread
			fEvaluationThread = new Thread(new Runnable() {
				public void run() {
					while (!fStopped) {
						synchronized (fLock) {
							doEvaluation();
							try {
								// Sleep until the next evaluation
								if (!fStopped) {
									fLock.wait();
								}
							} catch (InterruptedException exception) {
							}
						}
					}
				}
			}, "Evaluation thread"); //$NON-NLS-1$
			fEvaluationThread.start();
		} else {
			// Use the existing thread
			synchronized (fLock) {
				fLock.notifyAll();
			}
		}
	}

	/**
	 * Do the actual work of an evaluation. This method
	 * is intended to be called from within the underlying
	 * evaluation thread.
	 */
	private void doEvaluation() {
		fEvaluating = true;
		EvaluationResult result = new EvaluationResult(fEngine, fExpression.getSnippet(), fThread);
		if (fExpression.hasErrors()) {
			Message[] errors = fExpression.getErrors();
			for (int i = 0, numErrors = errors.length; i < numErrors; i++) {
				result.addError(errors[i]);
			}
			evaluationFinished(result);
			return;
		}
		fInterpreter = new Interpreter((InstructionSequence) fExpression, fContext);
		
		class EvaluationRunnable implements IEvaluationRunnable, ITerminate {
			public void run(IJavaThread jt, IProgressMonitor pm) {
				try {
					fInterpreter.execute();
				} catch (CoreException exception) {
					fException = exception;
				} catch (Throwable exception) {
					JDIDebugPlugin.log(exception);
					fException = new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IStatus.ERROR, InstructionsEvaluationMessages.getString("InstructionSequence.Runtime_exception_occurred_during_evaluation._See_log_for_details_1"), exception)); //$NON-NLS-1$
				}
			}
			public void terminate() {
				fInterpreter.stop();
			}
			public boolean canTerminate() {
				return true;
			}
			public boolean isTerminated() {
				return false;
			}
		}

		IEvaluationRunnable er = new EvaluationRunnable();
		CoreException exception = null;
		try {
			fThread.runEvaluation(er, null, fEvaluationDetail, fHitBreakpoints);
		} catch (DebugException e) {
			exception = e;
		}
		IJavaValue value = fInterpreter.getResult();

		if (exception == null) {
			exception = fException;
		}

		if (value != null) {
			result.setValue(value);
		} else {
			result.addError(new Message(EvaluationEngineMessages.getString("EvaluationThread.An_unknown_error_occurred_during_evaluation_1"), 0)); //$NON-NLS-1$
		}
		if (exception != null) {
			if (exception instanceof DebugException) {
				result.setException((DebugException)exception);
			} else {
				result.setException(new DebugException(exception.getStatus()));
			}
		}
		evaluationFinished(result);
	}
	
	/**
	 * Notifies the listener and the evaluation engine that
	 * this thread has finished an evaluation.
	 */
	private void evaluationFinished(IEvaluationResult result) {
		fEngine.evaluationThreadFinished(this);
		// only notify if plugin not yet shutdown - bug# 8693
		if(JDIDebugPlugin.getDefault() != null) {
			fListener.evaluationComplete(result);
		}
		fExpression= null;
		fContext= null;
		fThread= null;
		fListener= null;
		fException= null;
		fEvaluating = false;
	}
}