/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.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 = Integer.valueOf(0);
	/**
	 * Flag indicating that this breakpoint last suspended execution due to a
	 * field modification
	 */
	protected static final Integer MODIFICATION_EVENT = Integer.valueOf(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 = monitor -> {
			setMarker(resource.createMarker(JAVA_WATCHPOINT));

			// add attributes
			addLineBreakpointAttributes(attributes, getModelIdentifier(),
					true, lineNumber, charStart, charEnd);
			addTypeNameAndHitCount(attributes, typeName, hitCount);
			attributes.put(SUSPEND_POLICY, Integer.valueOf(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,
					new VMDisconnectedException());
		}
		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] = Boolean.valueOf(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;
	}
}
