/*******************************************************************************
 * 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<>(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;
	}
}
