/*******************************************************************************
 * Copyright (c) 2009, 2017 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.jdt.internal.debug.core.breakpoints;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.dom.Message;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
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.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDINullValue;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jdt.internal.debug.core.model.JDIValue;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.VMDisconnectedException;

/**
 * Breakpoint listener to handle breakpoint conditions.
 *
 * @since 3.5
 */
public class ConditionalBreakpointHandler implements IJavaBreakpointListener {

	/**
	 * Whether the condition had compile or runtime errors
	 */
	private boolean fHasErrors = false;

	/**
	 * Listens for evaluation completion for condition evaluation. If an
	 * evaluation evaluates <code>true</code> or has an error, this breakpoint
	 * will suspend the thread in which the breakpoint was hit. If the
	 * evaluation returns <code>false</code>, the thread is resumed.
	 */
	class EvaluationListener implements IEvaluationListener {

		/**
		 * Lock for synchronizing evaluation
		 */
		private Object fLock = new Object();

		/**
		 * The breakpoint that was hit
		 */
		private JavaLineBreakpoint fBreakpoint;

		/**
		 * Result of the vote
		 */
		private int fVote;

		EvaluationListener(JavaLineBreakpoint breakpoint) {
			fBreakpoint = breakpoint;
		}

		@Override
		public void evaluationComplete(IEvaluationResult result) {
			fVote = determineVote(result);
			synchronized (fLock) {
				fLock.notifyAll();
			}
		}

		/**
		 * Processes the result to determine whether to suspend or resume.
		 *
		 * @param result
		 *            evaluation result
		 * @return vote
		 */
		private int determineVote(IEvaluationResult result) {
			if (result.isTerminated()) {
				// indicates the user terminated the evaluation
				return SUSPEND;
			}
			JDIThread thread = (JDIThread) result.getThread();
			if (result.hasErrors()) {
				DebugException exception = result.getException();
				Throwable wrappedException = exception.getStatus()
						.getException();
				if (wrappedException instanceof VMDisconnectedException) {
					// VM terminated/disconnected during evaluation
					return DONT_SUSPEND;
				}
				fireConditionHasRuntimeErrors(fBreakpoint, exception);
				return SUSPEND;
			}
			try {
				IValue value = result.getValue();
				if (fBreakpoint.isConditionSuspendOnTrue()) {
					if (value instanceof IJavaPrimitiveValue) {
						// Suspend when the condition evaluates true
						IJavaPrimitiveValue javaValue = (IJavaPrimitiveValue) value;
						if (javaValue.getJavaType().getName()
								.equals("boolean")) { //$NON-NLS-1$
							if (javaValue.getBooleanValue()) {
								return SUSPEND;
							}
							return DONT_SUSPEND;
						}
					}
					if ((value instanceof JDIValue) && !(value instanceof JDINullValue)) {
						JDIValue jdiValue = (JDIValue)value;
						// Suspend if return is Boolean(true) else don't suspend (no error dialog)
						if (jdiValue.getJavaType().getName().equals("java.lang.Boolean")) {//$NON-NLS-1$
							IJavaPrimitiveValue javaValue = (IJavaPrimitiveValue) ((IJavaObject) jdiValue).getField("value", false).getValue(); //$NON-NLS-1$
							if (javaValue.getBooleanValue()) {
								return SUSPEND;
							}
							return DONT_SUSPEND;
						}
						return DONT_SUSPEND;
					}
					IStatus status = new Status(
							IStatus.ERROR,
							JDIDebugPlugin.getUniqueIdentifier(),
							MessageFormat.format(JDIDebugBreakpointMessages.ConditionalBreakpointHandler_1, value.getReferenceTypeName()));
					// result was not JDIValue
					fireConditionHasRuntimeErrors(fBreakpoint, new DebugException(status));
					return SUSPEND;
				}
				IDebugTarget debugTarget = thread.getDebugTarget();
				IValue lastValue = fBreakpoint
						.setCurrentConditionValue(debugTarget, value);
				if (!value.equals(lastValue)) {
					return SUSPEND;
				}
				return DONT_SUSPEND;
			} catch (DebugException e) {
				// Suspend when an error occurs
				JDIDebugPlugin.log(e);
				return SUSPEND;
			}
		}

		/**
		 * Result of the conditional expression evaluation - to resume or not
		 * resume, that is the question.
		 *
		 * @return vote result
		 */
		int getVote() {
			return fVote;
		}

		/**
		 * Returns the lock object to synchronize this evaluation.
		 *
		 * @return lock object
		 */
		Object getLock() {
			return fLock;
		}
	}

	@Override
	public void addingBreakpoint(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
	}

	@Override
	public void breakpointHasCompilationErrors(IJavaLineBreakpoint breakpoint,
			Message[] errors) {
	}

	@Override
	public void breakpointHasRuntimeException(IJavaLineBreakpoint breakpoint,
			DebugException exception) {
	}

	@Override
	public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
		if (breakpoint instanceof IJavaLineBreakpoint) {
			JavaLineBreakpoint lineBreakpoint = (JavaLineBreakpoint) breakpoint;
			try {
				final String condition = lineBreakpoint.getCondition();
				if (condition == null) {
					return SUSPEND;
				}
				EvaluationListener listener = new EvaluationListener(
						lineBreakpoint);
				IJavaStackFrame frame = (IJavaStackFrame) thread
						.getTopStackFrame();
				IJavaProject project = lineBreakpoint.getJavaProject(frame);
				if (project == null) {
					fireConditionHasErrors(
							lineBreakpoint,
							new Message[] { new Message(
									JDIDebugBreakpointMessages.JavaLineBreakpoint_Unable_to_compile_conditional_breakpoint___missing_Java_project_context__1,
									-1) });
					return SUSPEND;
				}
				IJavaDebugTarget target = (IJavaDebugTarget) thread
						.getDebugTarget();
				IAstEvaluationEngine engine = getEvaluationEngine(target,
						project);
				if (engine == null) {
					// If no engine is available, suspend
					return SUSPEND;
				}
				ICompiledExpression expression = lineBreakpoint
						.getExpression(thread);
				if (expression == null) {
					expression = engine.getCompiledExpression(condition, frame);
					lineBreakpoint.setExpression(thread, expression);
				}
				if (expression.hasErrors()) {
					fireConditionHasErrors(lineBreakpoint,
							getMessages(expression));
					return SUSPEND;
				}
				Object lock = listener.getLock();
				synchronized (lock) {
					engine.evaluateExpression(expression, frame, listener,
							DebugEvent.EVALUATION_IMPLICIT, false);
					// TODO: timeout?
					try {
						lock.wait();
					} catch (InterruptedException e) {
						fireConditionHasRuntimeErrors(
								lineBreakpoint,
								new DebugException(
										new Status(
												IStatus.ERROR,
												JDIDebugPlugin
														.getUniqueIdentifier(),
												JDIDebugBreakpointMessages.ConditionalBreakpointHandler_0,
												e)));
						return SUSPEND;
					}
				}
				return listener.getVote();
			} catch (CoreException e) {
				DebugException de = null;
				if (e instanceof DebugException) {
					de = (DebugException) e;
				} else {
					de = new DebugException(e.getStatus());
				}
				fireConditionHasRuntimeErrors(lineBreakpoint, de);
			}
		}
		return SUSPEND;
	}

	@Override
	public void breakpointInstalled(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
	}

	@Override
	public void breakpointRemoved(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
	}

	@Override
	public int installingBreakpoint(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint, IJavaType type) {
		return 0;
	}

	/**
	 * Returns an evaluation engine for evaluating this breakpoint's condition
	 * in the given target and project context.
	 * @param vm the VM to get an evaluation engine for
	 * @param project the project context
	 * @return a new {@link IAstEvaluationEngine}
	 */
	private IAstEvaluationEngine getEvaluationEngine(IJavaDebugTarget vm, IJavaProject project) {
		return ((JDIDebugTarget) vm).getEvaluationEngine(project);
	}

	private void fireConditionHasRuntimeErrors(IJavaLineBreakpoint breakpoint, DebugException exception) {
		fHasErrors = true;
		JDIDebugPlugin.getDefault().fireBreakpointHasRuntimeException(breakpoint, exception);
	}

	/**
	 * Notifies listeners that a conditional breakpoint expression has been
	 * compiled that contains errors
	 * @param breakpoint the breakpoint that has errors in its condition
	 * @param messages the error messages
	 */
	private void fireConditionHasErrors(IJavaLineBreakpoint breakpoint, Message[] messages) {
		fHasErrors = true;
		JDIDebugPlugin.getDefault().fireBreakpointHasCompilationErrors(breakpoint, messages);
	}

	/**
	 * Convert an array of <code>String</code> to an array of
	 * <code>Message</code>.
	 * @param expression the expression to get messages from
	 * @return the array of {@link Message}s from the expression
	 */
	private Message[] getMessages(ICompiledExpression expression) {
		String[] errorMessages = expression.getErrorMessages();
		Message[] messages = new Message[errorMessages.length];
		for (int i = 0; i < messages.length; i++) {
			messages[i] = new Message(errorMessages[i], -1);
		}
		return messages;
	}

	/**
	 * Returns whether errors were encountered when evaluating the condition
	 * (compilation or runtime).
	 *
	 * @return whether errors were encountered when evaluating the condition
	 */
	public boolean hasErrors() {
		return fHasErrors;
	}
}
