/*******************************************************************************
 * Copyright (c) 2000, 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 java.util.HashMap;
import java.util.Map;

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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;

import com.sun.jdi.Field;
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.AccessWatchpointEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.ModificationWatchpointEvent;
import com.sun.jdi.request.AccessWatchpointRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.ModificationWatchpointRequest;
import com.sun.jdi.request.WatchpointRequest;

public class JavaWatchpoint extends JavaLineBreakpoint implements
		IJavaWatchpoint {

	public static final String JAVA_WATCHPOINT = "org.eclipse.jdt.debug.javaWatchpointMarker"; //$NON-NLS-1$
	/**
	 * Watchpoint attribute storing the access value (value
	 * <code>"org.eclipse.jdt.debug.core.access"</code>). This attribute is
	 * stored as a <code>boolean</code>, indicating whether a watchpoint is an
	 * access watchpoint.
	 */
	protected static final String ACCESS = "org.eclipse.jdt.debug.core.access"; //$NON-NLS-1$
	/**
	 * Watchpoint attribute storing the modification value (value
	 * <code>"org.eclipse.jdt.debug.core.modification"</code>). This attribute
	 * is stored as a <code>boolean</code>, indicating whether a watchpoint is a
	 * modification watchpoint.
	 */
	protected static final String MODIFICATION = "org.eclipse.jdt.debug.core.modification"; //$NON-NLS-1$	
	/**
	 * Watchpoint attribute storing the auto_disabled value (value
	 * <code>"org.eclipse.jdt.debug.core.auto_disabled"</code>). This attribute
	 * is stored as a <code>boolean</code>, indicating whether a watchpoint has
	 * been auto-disabled (as opposed to being disabled explicitly by the user)
	 */
	protected static final String AUTO_DISABLED = "org.eclipse.jdt.debug.core.auto_disabled"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing the name of the field on which a breakpoint
	 * is set. (value <code>"org.eclipse.jdt.debug.core.fieldName"</code>). This
	 * attribute is a <code>String</code>.
	 */
	protected static final String FIELD_NAME = "org.eclipse.jdt.debug.core.fieldName"; //$NON-NLS-1$		
	/**
	 * Flag indicating that this breakpoint last suspended execution due to a
	 * field access
	 */
	protected static final Integer ACCESS_EVENT = new Integer(0);
	/**
	 * Flag indicating that this breakpoint last suspended execution due to a
	 * field modification
	 */
	protected static final Integer MODIFICATION_EVENT = new Integer(1);
	/**
	 * Maps each debug target that is suspended for this breakpoint to reason
	 * that this breakpoint suspended it. Reasons include:
	 * <ol>
	 * <li>Field access (value <code>ACCESS_EVENT</code>)</li>
	 * <li>Field modification (value <code>MODIFICATION_EVENT</code>)</li>
	 * </ol>
	 */
	private HashMap<JDIDebugTarget, Integer> fLastEventTypes = new HashMap<JDIDebugTarget, Integer>(10);

	public JavaWatchpoint() {
	}

	/**
	 * @see JDIDebugModel#createWatchpoint(IResource, String, String, int, int,
	 *      int, int, boolean, Map)
	 */
	public JavaWatchpoint(final IResource resource, final String typeName,
			final String fieldName, final int lineNumber, final int charStart,
			final int charEnd, final int hitCount, final boolean add,
			final Map<String, Object> attributes) throws DebugException {
		IWorkspaceRunnable wr = new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				setMarker(resource.createMarker(JAVA_WATCHPOINT));

				// add attributes
				addLineBreakpointAttributes(attributes, getModelIdentifier(),
						true, lineNumber, charStart, charEnd);
				addTypeNameAndHitCount(attributes, typeName, hitCount);
				attributes.put(SUSPEND_POLICY, new Integer(
						getDefaultSuspendPolicy()));
				// configure the field handle
				addFieldName(attributes, fieldName);
				// configure the access and modification flags to defaults
				addDefaultAccessAndModification(attributes);

				// set attributes
				ensureMarker().setAttributes(attributes);

				register(add);
			}
		};
		run(getMarkerRule(resource), wr);
	}

	/**
	 * @see JavaBreakpoint#createRequest(JDIDebugTarget, ReferenceType)
	 * 
	 *      Creates and installs an access and modification watchpoint request
	 *      in the given reference type, configuring the requests as appropriate
	 *      for this watchpoint. The requests are then enabled based on whether
	 *      this watchpoint is an access watchpoint, modification watchpoint, or
	 *      both. Finally, the requests are registered with the given target.
	 */
	@Override
	protected boolean createRequest(JDIDebugTarget target, ReferenceType type)
			throws CoreException {
		if (shouldSkipBreakpoint()) {
			return false;
		}
		Field field = null;

		field = type.fieldByName(getFieldName());
		if (field == null) {
			// error
			return false;
		}
		AccessWatchpointRequest accessRequest = null;
		ModificationWatchpointRequest modificationRequest = null;
		if (target.supportsAccessWatchpoints()) {
			accessRequest = createAccessWatchpoint(target, field);
			registerRequest(accessRequest, target);
		} else {
			notSupported(JDIDebugBreakpointMessages.JavaWatchpoint_no_access_watchpoints);
		}
		if (target.supportsModificationWatchpoints()) {
			modificationRequest = createModificationWatchpoint(target, field);
			if (modificationRequest == null) {
				return false;
			}
			registerRequest(modificationRequest, target);
			return true;
		}
		notSupported(JDIDebugBreakpointMessages.JavaWatchpoint_no_modification_watchpoints);
		return false;
	}

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

	/**
	 * Either access or modification watchpoints are not supported. Throw an
	 * appropriate exception.
	 * 
	 * @param message
	 *            the message that states that access or modification
	 *            watchpoints are not supported
	 */
	protected void notSupported(String message) throws DebugException {
		throw new DebugException(new Status(IStatus.ERROR,
				DebugPlugin.getUniqueIdentifier(),
				DebugException.NOT_SUPPORTED, message, null)); //
	}

	/**
	 * Create an access watchpoint for the given breakpoint and associated field
	 */
	protected AccessWatchpointRequest createAccessWatchpoint(
			JDIDebugTarget target, Field field) throws CoreException {
		return (AccessWatchpointRequest) createWatchpoint(target, field, true);
	}

	/**
	 * Create a modification watchpoint for the given breakpoint and associated
	 * field
	 */
	protected ModificationWatchpointRequest createModificationWatchpoint(
			JDIDebugTarget target, Field field) throws CoreException {
		return (ModificationWatchpointRequest) createWatchpoint(target, field,
				false);
	}

	/**
	 * Create a watchpoint for the given breakpoint and associated field.
	 * 
	 * @param target
	 *            the target in which the request will be installed
	 * @param field
	 *            the field on which the request will be set
	 * @param access
	 *            <code>true</code> if an access watchpoint will be created.
	 *            <code>false</code> if a modification watchpoint will be
	 *            created.
	 * 
	 * @return an WatchpointRequest (AccessWatchpointRequest if access is
	 *         <code>true</code>; ModificationWatchpointRequest if access is
	 *         <code>false</code>).
	 */
	protected WatchpointRequest createWatchpoint(JDIDebugTarget target,
			Field field, boolean access) throws CoreException {
		WatchpointRequest request = null;
		EventRequestManager manager = target.getEventRequestManager();
		if (manager == null) {
			target.requestFailed(
					JDIDebugBreakpointMessages.JavaWatchpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
					null);
		}
		try {
			if (access) {
				request = manager.createAccessWatchpointRequest(field);
			} else {
				request = manager.createModificationWatchpointRequest(field);
			}
			configureRequest(request, target);
		} catch (VMDisconnectedException e) {
			if (!target.isAvailable()) {
				return null;
			}
			target.internalError(e);
			return null;
		} catch (RuntimeException e) {
			target.internalError(e);
			return null;
		}
		return request;
	}

	/**
	 * @see JavaBreakpoint#recreateRequest(EventRequest, JDIDebugTarget)
	 */
	protected EventRequest recreateRequest(EventRequest request,
			JDIDebugTarget target) throws CoreException {
		try {
			Field field = ((WatchpointRequest) request).field();
			if (request instanceof AccessWatchpointRequest) {
				request = createAccessWatchpoint(target, field);
			} else if (request instanceof ModificationWatchpointRequest) {
				request = createModificationWatchpoint(target, field);
			}
		} catch (VMDisconnectedException e) {
			if (!target.isAvailable()) {
				return request;
			}
			target.internalError(e);
			return request;
		} catch (RuntimeException e) {
			target.internalError(e);
		}
		return request;
	}

	/**
	 * @see IBreakpoint#setEnabled(boolean)
	 * 
	 *      If the watchpoint is not watching access or modification, set the
	 *      default values. If this isn't done, the resulting state (enabled
	 *      with access and modification both disabled) is ambiguous.
	 */
	@Override
	public void setEnabled(boolean enabled) throws CoreException {
		if (enabled) {
			if (!(isAccess() || isModification())) {
				setDefaultAccessAndModification();
			}
		}
		super.setEnabled(enabled);
	}

	/**
	 * @see org.eclipse.debug.core.model.IWatchpoint#isAccess()
	 */
	@Override
	public boolean isAccess() throws CoreException {
		return ensureMarker().getAttribute(ACCESS, false);
	}

	/**
	 * Sets whether this breakpoint will suspend execution when its associated
	 * field is accessed. If true and this watchpoint is disabled, this
	 * watchpoint is automatically enabled. If both access and modification are
	 * false, this watchpoint is automatically disabled.
	 * 
	 * @param access
	 *            whether to suspend on field access
	 * @exception CoreException
	 *                if unable to set the property on this breakpoint's
	 *                underlying marker
	 * @see org.eclipse.debug.core.model.IWatchpoint#setAccess(boolean)
	 */
	@Override
	public void setAccess(boolean access) throws CoreException {
		if (access == isAccess()) {
			return;
		}
		setAttribute(ACCESS, access);
		if (access && !isEnabled()) {
			setEnabled(true);
		} else if (!(access || isModification())) {
			setEnabled(false);
		}
		recreate();
	}

	/**
	 * @see org.eclipse.debug.core.model.IWatchpoint#isModification()
	 */
	@Override
	public boolean isModification() throws CoreException {
		return ensureMarker().getAttribute(MODIFICATION, false);
	}

	/**
	 * Sets whether this breakpoint will suspend execution when its associated
	 * field is modified. If true and this watchpoint is disabled, this
	 * watchpoint is automatically enabled. If both access and modification are
	 * false, this watchpoint is automatically disabled.
	 * 
	 * @param modification
	 *            whether to suspend on field modification
	 * @exception CoreException
	 *                if unable to set the property on this breakpoint's
	 *                underlying marker
	 * @see org.eclipse.debug.core.model.IWatchpoint#setModification(boolean)
	 */
	@Override
	public void setModification(boolean modification) throws CoreException {
		if (modification == isModification()) {
			return;
		}
		setAttribute(MODIFICATION, modification);
		if (modification && !isEnabled()) {
			setEnabled(true);
		} else if (!(modification || isAccess())) {
			setEnabled(false);
		}
		recreate();
	}

	/**
	 * Sets the default access and modification attributes of the watchpoint.
	 * The default values are:
	 * <ul>
	 * <li>access = <code>false</code>
	 * <li>modification = <code>true</code>
	 * <ul>
	 */
	protected void setDefaultAccessAndModification() throws CoreException {
		boolean[] def = getDefaultAccessAndModificationValues();
		Object[] values = new Object[def.length];
		for (int i = 0; i < def.length; i++) {
			values[i] = new Boolean(def[i]);
		}
		String[] attributes = new String[] { ACCESS, MODIFICATION };
		setAttributes(attributes, values);
	}

	/**
	 * Returns the default access and modification suspend option for a new
	 * watchpoint based on the user preference settings The return array will
	 * only ever contain two values, where the possibilities are:
	 * <ul>
	 * <li> <code>{true, true}</code> - both access and modification are enabled</li>
	 * <li> <code>{true, false}</code> - access is enabled and modification is
	 * disabled</li>
	 * <li> <code>{false, true}</code> -access is disabled and modification is
	 * enabled</li>
	 * </ul>
	 * The default returned array is <code>{true, true}</code>
	 * 
	 * @return an array of two boolean values representing the default access
	 *         and modification settings
	 * 
	 * @since 3.3.1
	 */
	protected boolean[] getDefaultAccessAndModificationValues() {
		int value = Platform.getPreferencesService().getInt(
				JDIDebugPlugin.getUniqueIdentifier(), 
				JDIDebugPlugin.PREF_DEFAULT_WATCHPOINT_SUSPEND_POLICY, 
				0, 
				null);
		switch (value) {
		case 0: {
			return new boolean[] { true, true };
		}
		case 1: {
			return new boolean[] { true, false };
		}
		case 2: {
			return new boolean[] { false, true };
		}
		default: {
			return new boolean[] { true, true };
		}
		}
	}

	/**
	 * Adds the default access and modification attributes of the watchpoint to
	 * the given map
	 * <ul>
	 * <li>access = true
	 * <li>modification = true
	 * <li>auto disabled = false
	 * <ul>
	 */
	protected void addDefaultAccessAndModification(Map<String, Object> attributes) {
		boolean[] values = getDefaultAccessAndModificationValues();
		attributes.put(ACCESS, (values[0] ? Boolean.TRUE : Boolean.FALSE));
		attributes
				.put(MODIFICATION, (values[1] ? Boolean.TRUE : Boolean.FALSE));
		attributes.put(AUTO_DISABLED, Boolean.FALSE);
	}

	/**
	 * Adds the field name to the given attribute map
	 */
	protected void addFieldName(Map<String, Object> attributes, String fieldName) {
		attributes.put(FIELD_NAME, fieldName);
	}

	/**
	 * @see IJavaWatchpoint#getFieldName()
	 */
	@Override
	public String getFieldName() throws CoreException {
		return ensureMarker().getAttribute(FIELD_NAME, null);
	}

	/**
	 * Store the type of the event, then handle it as specified in the
	 * superclass. This is useful for correctly generating the thread text when
	 * asked (assumes thread text is requested after the event is passed to this
	 * breakpoint.
	 * 
	 * Also, @see JavaBreakpoint#handleEvent(Event, JDIDebugTarget)
	 */
	@Override
	public boolean handleEvent(Event event, JDIDebugTarget target,
			boolean suspendVote, EventSet eventSet) {
		if (event instanceof AccessWatchpointEvent) {
			fLastEventTypes.put(target, ACCESS_EVENT);
		} else if (event instanceof ModificationWatchpointEvent) {
			fLastEventTypes.put(target, MODIFICATION_EVENT);
		}
		return super.handleEvent(event, target, suspendVote, eventSet);
	}

	/**
	 * @see JavaBreakpoint#updateEnabledState(EventRequest, JDIDebugTarget)
	 */
	@Override
	protected void updateEnabledState(EventRequest request,
			JDIDebugTarget target) throws CoreException {
		boolean enabled = isEnabled();
		if (request instanceof AccessWatchpointRequest) {
			if (isAccess()) {
				if (enabled != request.isEnabled()) {
					internalUpdateEnabledState(request, enabled, target);
				}
			} else {
				if (request.isEnabled()) {
					internalUpdateEnabledState(request, false, target);
				}
			}
		}
		if (request instanceof ModificationWatchpointRequest) {
			if (isModification()) {
				if (enabled != request.isEnabled()) {
					internalUpdateEnabledState(request, enabled, target);
				}
			} else {
				if (request.isEnabled()) {
					internalUpdateEnabledState(request, false, target);
				}
			}
		}
	}

	/**
	 * @see IJavaWatchpoint#isAccessSuspend(IDebugTarget)
	 */
	@Override
	public boolean isAccessSuspend(IDebugTarget target) {
		Integer lastEventType = fLastEventTypes.get(target);
		if (lastEventType == null) {
			return false;
		}
		return lastEventType.equals(ACCESS_EVENT);
	}

	/**
	 * @see IJavaLineBreakpoint#supportsCondition()
	 */
	@Override
	public boolean supportsCondition() {
		return true;
	}

	/**
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#removeFromTarget(JDIDebugTarget)
	 */
	@Override
	public void removeFromTarget(JDIDebugTarget target) throws CoreException {
		fLastEventTypes.remove(target);
		super.removeFromTarget(target);
	}

	/**
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addInstanceFilter(EventRequest,
	 *      ObjectReference)
	 */
	@Override
	protected void addInstanceFilter(EventRequest request,
			ObjectReference object) {
		if (request instanceof WatchpointRequest) {
			((WatchpointRequest) request).addInstanceFilter(object);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IWatchpoint#supportsAccess()
	 */
	@Override
	public boolean supportsAccess() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IWatchpoint#supportsModification()
	 */
	@Override
	public boolean supportsModification() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#
	 * installableReferenceType(com.sun.jdi.ReferenceType,
	 * org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
	 */
	@Override
	protected boolean installableReferenceType(ReferenceType type,
			JDIDebugTarget target) throws CoreException {
		String installableType = getTypeName();
		String queriedType = type.name();
		if (installableType == null || queriedType == null) {
			return false;
		}
		if (installableType.equals(queriedType)) {
			return queryInstallListeners(target, type);
		}

		return false;
	}
}
