/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Igor Fedorenko - Bug 368212 - JavaLineBreakpoint.computeJavaProject does not let ISourceLocator evaluate the stackFrame
 *     Jesper Møller  - Bug 422016 - [1.8] Having reference expressions or lambdas in file triggers warning for missing line numbers
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.breakpoints;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
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.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.jdi.internal.AccessibleImpl;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.eval.ICompiledExpression;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.Location;
import com.sun.jdi.NativeMethodException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.event.Event;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;

public class JavaLineBreakpoint extends JavaBreakpoint implements
		IJavaLineBreakpoint {

	/**
	 * Breakpoint attribute storing a breakpoint's conditional expression (value
	 * <code>"org.eclipse.jdt.debug.core.condition"</code>). This attribute is
	 * stored as a <code>String</code>.
	 */
	protected static final String CONDITION = "org.eclipse.jdt.debug.core.condition"; //$NON-NLS-1$
	/**
	 * Breakpoint attribute storing a breakpoint's condition enabled state
	 * (value <code>"org.eclipse.jdt.debug.core.conditionEnabled"</code>). This
	 * attribute is stored as an <code>boolean</code>.
	 */
	protected static final String CONDITION_ENABLED = "org.eclipse.jdt.debug.core.conditionEnabled"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing a breakpoint's condition suspend policy
	 * (value <code>" org.eclipse.jdt.debug.core.conditionSuspendOnTrue"
	 * </code>). This attribute is stored as an <code>boolean</code>.
	 */
	protected static final String CONDITION_SUSPEND_ON_TRUE = "org.eclipse.jdt.debug.core.conditionSuspendOnTrue"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing a breakpoint's source file name (debug
	 * attribute) (value <code>"org.eclipse.jdt.debug.core.sourceName"</code>).
	 * This attribute is stored as a <code>String</code>.
	 */
	protected static final String SOURCE_NAME = "org.eclipse.jdt.debug.core.sourceName"; //$NON-NLS-1$

	public static final String JAVA_LINE_BREAKPOINT = "org.eclipse.jdt.debug.javaLineBreakpointMarker"; //$NON-NLS-1$

	/**
	 * Maps suspended threads to the suspend event that suspended them
	 */
	private Map<IJavaThread, ICompiledExpression> fSuspendEvents = new HashMap<IJavaThread, ICompiledExpression>();
	/**
	 * The map of cached compiled expressions (ICompiledExpression) for this
	 * breakpoint, keyed by thread. This value must be cleared every time the
	 * breakpoint is added to a target.
	 */
	private Map<IJavaThread, ICompiledExpression> fCompiledExpressions = new HashMap<IJavaThread, ICompiledExpression>();

	/**
	 * Cache of projects for stack frames to avoid repetitive project resolution
	 * on conditional breakpoints.
	 */
	private Map<IJavaStackFrame, IJavaProject> fProjectsByFrame = new HashMap<IJavaStackFrame, IJavaProject>();

	/**
	 * The map of the result value of the condition (IValue) for this
	 * breakpoint, keyed by debug target.
	 */
	private Map<IDebugTarget, IValue> fConditionValues = new HashMap<IDebugTarget, IValue>();

	/**
	 * Status code indicating that a request to create a breakpoint in a type
	 * with no line number attributes has occurred.
	 */
	public static final int NO_LINE_NUMBERS = 162;

	public JavaLineBreakpoint() {
	}

	/**
	 * @see JDIDebugModel#createLineBreakpoint(IResource, String, int, int, int,
	 *      int, boolean, Map)
	 */
	public JavaLineBreakpoint(IResource resource, String typeName,
			int lineNumber, int charStart, int charEnd, int hitCount,
			boolean add, Map<String, Object> attributes) throws DebugException {
		this(resource, typeName, lineNumber, charStart, charEnd, hitCount, add,
				attributes, JAVA_LINE_BREAKPOINT);
	}

	protected JavaLineBreakpoint(final IResource resource,
			final String typeName, final int lineNumber, final int charStart,
			final int charEnd, final int hitCount, final boolean add,
			final Map<String, Object> attributes, final String markerType)
			throws DebugException {
		IWorkspaceRunnable wr = new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {

				// create the marker
				setMarker(resource.createMarker(markerType));

				// add attributes
				addLineBreakpointAttributes(attributes, getModelIdentifier(),
						true, lineNumber, charStart, charEnd);
				addTypeNameAndHitCount(attributes, typeName, hitCount);
				// set attributes
				attributes.put(SUSPEND_POLICY, new Integer(
						getDefaultSuspendPolicy()));
				ensureMarker().setAttributes(attributes);

				// add to breakpoint manager if requested
				register(add);
			}
		};
		run(getMarkerRule(resource), wr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addToTarget
	 * (org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
	 */
	@Override
	public void addToTarget(JDIDebugTarget target) throws CoreException {
		clearCachedExpressionFor(target);
		super.addToTarget(target);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#
	 * removeFromTarget
	 * (org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
	 */
	@Override
	public void removeFromTarget(JDIDebugTarget target) throws CoreException {
		clearCachedExpressionFor(target);
		clearCachedSuspendEvents(target);
		fConditionValues.remove(target);
		super.removeFromTarget(target);
	}

	/**
	 * Removes all suspend events which are currently being cached for threads
	 * in the given target.
	 */
	protected void clearCachedSuspendEvents(JDIDebugTarget target) {
		removeCachedThreads(fSuspendEvents, target);
	}

	private void removeCachedThreads(Map<IJavaThread, ICompiledExpression> map, JDIDebugTarget target) {
		Set<IJavaThread> threads = map.keySet();
		List<IJavaThread> threadsToRemove = new ArrayList<IJavaThread>();
		Iterator<IJavaThread> iter = threads.iterator();
		JDIThread thread;
		while (iter.hasNext()) {
			thread = (JDIThread) iter.next();
			if (thread.getDebugTarget() == target) {
				threadsToRemove.add(thread);
			}
		}
		iter = threadsToRemove.iterator();
		while (iter.hasNext()) {
			map.remove(iter.next());
		}
	}

	/**
	 * Removes all compiled expressions which are currently being cached for
	 * threads in the given target.
	 */
	protected void clearCachedExpressionFor(JDIDebugTarget target) {
		removeCachedThreads(fCompiledExpressions, target);

		// clean up cached projects for stack frames
		synchronized (fProjectsByFrame) {
			Set<IJavaStackFrame> frames = fProjectsByFrame.keySet();
			List<IJavaStackFrame> framesToRemove = new ArrayList<IJavaStackFrame>();
			Iterator<IJavaStackFrame> iter = frames.iterator();
			JDIStackFrame frame;
			while (iter.hasNext()) {
				frame = (JDIStackFrame) iter.next();
				if (frame.getDebugTarget() == target) {
					framesToRemove.add(frame);
				}
			}
			iter = framesToRemove.iterator();
			while (iter.hasNext()) {
				fProjectsByFrame.remove(iter.next());
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ILineBreakpoint#getLineNumber()
	 */
	@Override
	public int getLineNumber() throws CoreException {
		return ensureMarker().getAttribute(IMarker.LINE_NUMBER, -1);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ILineBreakpoint#getCharStart()
	 */
	@Override
	public int getCharStart() throws CoreException {
		return ensureMarker().getAttribute(IMarker.CHAR_START, -1);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ILineBreakpoint#getCharEnd()
	 */
	@Override
	public int getCharEnd() throws CoreException {
		return ensureMarker().getAttribute(IMarker.CHAR_END, -1);
	}

	/**
	 * Returns the type of marker associated with Java line breakpoints
	 */
	public static String getMarkerType() {
		return JAVA_LINE_BREAKPOINT;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#newRequest
	 * (org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget,
	 * com.sun.jdi.ReferenceType)
	 */
	@Override
	protected EventRequest[] newRequests(JDIDebugTarget target,
			ReferenceType type) throws CoreException {
		int lineNumber = getLineNumber();
		List<Location> locations = determineLocations(lineNumber, type, target);
		if (locations == null || locations.isEmpty()) {
			// could be an inner type not yet loaded, or line information not
			// available
			return null;
		}
		EventRequest[] requests = new EventRequest[locations.size()];
		int i = 0;
		for(Location location : locations) {
			requests[i] = createLineBreakpointRequest(location, target);
			i++;
		}
		return requests;
	}

	/**
	 * Creates, installs, and returns a line breakpoint request at the given
	 * location for this breakpoint.
	 */
	protected BreakpointRequest createLineBreakpointRequest(Location location,
			JDIDebugTarget target) throws CoreException {
		BreakpointRequest request = null;
		EventRequestManager manager = target.getEventRequestManager();
		if (manager != null) {
			try {
				request = manager.createBreakpointRequest(location);
				configureRequest(request, target);
			} catch (VMDisconnectedException e) {
				if (!target.isAvailable()) {
					return null;
				}
				JDIDebugPlugin.log(e);
			} catch (RuntimeException e) {
				target.internalError(e);
				return null;
			}
			return request;
		}
		target.requestFailed(
				JDIDebugBreakpointMessages.JavaLineBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
				null);
		return null;
	}

	/**
	 * @see JavaBreakpoint#setRequestThreadFilter(EventRequest)
	 */
	@Override
	protected void setRequestThreadFilter(EventRequest request,
			ThreadReference thread) {
		((BreakpointRequest) request).addThreadFilter(thread);
	}

	/**
	 * Returns a list of locations of the given line number in the given type.
	 * Returns <code>null</code> if locations cannot be determined.
	 */
	protected List<Location> determineLocations(int lineNumber, ReferenceType type,
			JDIDebugTarget target) {
		List<Location> locations = null;
		try {
			locations = type.locationsOfLine(JavaDebugUtils.JAVA_STRATUM, null, lineNumber);
		} catch (AbsentInformationException aie) {
			if (((type.modifiers() & (AccessibleImpl.MODIFIER_ACC_SYNTHETIC | AccessibleImpl.MODIFIER_SYNTHETIC)) != 0)||(type instanceof InterfaceType)) {
				return null;
			}
			
			IStatus status = new Status(
					IStatus.ERROR,
					JDIDebugPlugin.getUniqueIdentifier(),
					NO_LINE_NUMBERS,
					JDIDebugBreakpointMessages.JavaLineBreakpoint_Absent_Line_Number_Information_1,
					null);
			IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(
					status);
			if (handler != null) {
				try {
					handler.handleStatus(status, type);
				} catch (CoreException e) {
				}
			}
			return null;
		} catch (NativeMethodException e) {
			return null;
		} catch (VMDisconnectedException e) {
			return null;
		} catch (ClassNotPreparedException e) {
			// could be a nested type that is not yet loaded
			return null;
		} catch (RuntimeException e) {
			// not able to retrieve line information
			target.internalError(e);
			return null;
		}
		return locations;
	}

	/**
	 * Adds the standard attributes of a line breakpoint to the given attribute
	 * map. The standard attributes are:
	 * <ol>
	 * <li>IBreakpoint.ID</li>
	 * <li>IBreakpoint.ENABLED</li>
	 * <li>IMarker.LINE_NUMBER</li>
	 * <li>IMarker.CHAR_START</li>
	 * <li>IMarker.CHAR_END</li>
	 * </ol>
	 * 
	 */
	public void addLineBreakpointAttributes(Map<String, Object> attributes,
			String modelIdentifier, boolean enabled, int lineNumber,
			int charStart, int charEnd) {
		attributes.put(IBreakpoint.ID, modelIdentifier);
		attributes.put(IBreakpoint.ENABLED, Boolean.valueOf(enabled));
		attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber));
		attributes.put(IMarker.CHAR_START, new Integer(charStart));
		attributes.put(IMarker.CHAR_END, new Integer(charEnd));
	}

	/**
	 * Adds type name and hit count attributes to the given map.
	 * 
	 * If <code>hitCount > 0</code>, adds the <code>HIT_COUNT</code> attribute
	 * to the given breakpoint, and resets the <code>EXPIRED</code> attribute to
	 * false (since, if the hit count is changed, the breakpoint should no
	 * longer be expired).
	 */
	public void addTypeNameAndHitCount(Map<String, Object> attributes, String typeName,
			int hitCount) {
		attributes.put(TYPE_NAME, typeName);
		if (hitCount > 0) {
			attributes.put(HIT_COUNT, new Integer(hitCount));
			attributes.put(EXPIRED, Boolean.FALSE);
		}
	}

	/**
	 * Returns whether this breakpoint has an enabled condition
	 */
	public boolean hasCondition() {
		try {
			String condition = getCondition();
			return isConditionEnabled() && condition != null
					&& (condition.length() > 0);
		} catch (CoreException exception) {
			JDIDebugPlugin.log(exception);
			return false;
		}
	}

	/**
	 * Suspends the given thread for the given breakpoint event. Returns whether
	 * the thread suspends.
	 */
	protected boolean suspendForEvent(Event event, JDIThread thread,
			boolean suspendVote) {
		expireHitCount(event);
		inActivateTriggerPoint(event);
		return suspend(thread, suspendVote);
	}

	protected IJavaProject getJavaProject(IJavaStackFrame stackFrame) {
		synchronized (fProjectsByFrame) {
			IJavaProject project = fProjectsByFrame.get(stackFrame);
			if (project == null) {
				project = JavaDebugUtils.resolveJavaProject(stackFrame);
				if (project != null) {
					fProjectsByFrame.put(stackFrame, project);
				}
			}
			return project;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#supportsCondition()
	 */
	@Override
	public boolean supportsCondition() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#getCondition()
	 */
	@Override
	public String getCondition() throws CoreException {
		return ensureMarker().getAttribute(CONDITION, null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setCondition(java.lang
	 * .String)
	 */
	@Override
	public void setCondition(String condition) throws CoreException {
		// Clear the cached compiled expressions
		fCompiledExpressions.clear();
		fConditionValues.clear();
		fSuspendEvents.clear();
		if (condition != null && condition.trim().length() == 0) {
			condition = null;
		}
		setAttributes(new String[] { CONDITION }, new Object[] { condition });
		recreate();
	}

	protected String getMarkerMessage(boolean conditionEnabled,
			String condition, int hitCount, int suspendPolicy, int lineNumber) {
		StringBuffer message = new StringBuffer(super.getMarkerMessage(
				hitCount, suspendPolicy));
		if (lineNumber != -1) {
			message.append(MessageFormat
					.format(JDIDebugBreakpointMessages.JavaLineBreakpoint___line___0___1,
							new Object[] { Integer.toString(lineNumber) }));
		}
		if (conditionEnabled && condition != null) {
			message.append(MessageFormat
					.format(JDIDebugBreakpointMessages.JavaLineBreakpoint___Condition___0___2,
							new Object[] { condition }));
		}

		return message.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#isConditionEnabled()
	 */
	@Override
	public boolean isConditionEnabled() throws CoreException {
		return ensureMarker().getAttribute(CONDITION_ENABLED, false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setConditionEnabled(boolean
	 * )
	 */
	@Override
	public void setConditionEnabled(boolean conditionEnabled)
			throws CoreException {
		setAttributes(new String[] { CONDITION_ENABLED },
				new Object[] { Boolean.valueOf(conditionEnabled) });
		recreate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#
	 * cleanupForThreadTermination
	 * (org.eclipse.jdt.internal.debug.core.model.JDIThread)
	 */
	@Override
	protected void cleanupForThreadTermination(JDIThread thread) {
		fSuspendEvents.remove(thread);
		fCompiledExpressions.remove(thread);
		super.cleanupForThreadTermination(thread);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#
	 * addInstanceFilter(com.sun.jdi.request.EventRequest,
	 * com.sun.jdi.ObjectReference)
	 */
	@Override
	protected void addInstanceFilter(EventRequest request,
			ObjectReference object) {
		if (request instanceof BreakpointRequest) {
			((BreakpointRequest) request).addInstanceFilter(object);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaLineBreakpoint#isConditionSuspendOnTrue()
	 */
	@Override
	public boolean isConditionSuspendOnTrue() throws DebugException {
		return ensureMarker().getAttribute(CONDITION_SUSPEND_ON_TRUE, true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setConditionSuspendOnTrue
	 * (boolean)
	 */
	@Override
	public void setConditionSuspendOnTrue(boolean suspendOnTrue)
			throws CoreException {
		if (isConditionSuspendOnTrue() != suspendOnTrue) {
			setAttributes(new String[] { CONDITION_SUSPEND_ON_TRUE },
					new Object[] { Boolean.valueOf(suspendOnTrue) });
			fConditionValues.clear();
			recreate();
		}
	}

	/**
	 * Returns existing compiled expression for the given thread or
	 * <code>null</code>.
	 * 
	 * @param thread
	 *            thread the breakpoint was hit in
	 * @return compiled expression or <code>null</code>
	 */
	protected ICompiledExpression getExpression(IJavaThread thread) {
		return fCompiledExpressions.get(thread);
	}

	/**
	 * Sets the compiled expression for a thread.
	 * 
	 * @param thread
	 *            thread the breakpoint was hit in
	 * @param expression
	 *            associated compiled expression
	 */
	protected void setExpression(IJavaThread thread,
			ICompiledExpression expression) {
		fCompiledExpressions.put(thread, expression);
	}

	/**
	 * Sets the current result value of the conditional expression evaluation
	 * for this breakpoint in the given target, and returns the previous value
	 * or <code>null</code> if none
	 * 
	 * @param target
	 *            debug target
	 * @param value
	 *            current expression value
	 * @return previous value or <code>null</code>
	 */
	protected IValue setCurrentConditionValue(IDebugTarget target, IValue value) {
		IValue prev = fConditionValues.get(target);
		fConditionValues.put(target, value);
		return prev;
	}

}
