/*******************************************************************************
 * Copyright (c) 2000, 2012 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.ui;


import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;

/**
 * Utility class for Java breakpoints
 */
public class BreakpointUtils {

	/**
	 * Marker attribute storing the handle id of the
	 * Java element associated with a Java breakpoint
	 */
	private static final String HANDLE_ID = JDIDebugUIPlugin.getUniqueIdentifier() + ".JAVA_ELEMENT_HANDLE_ID"; //$NON-NLS-1$

	/**
	 * Marker attribute used to denote a run to line breakpoint
	 */
	private static final String RUN_TO_LINE =  JDIDebugUIPlugin.getUniqueIdentifier() + ".run_to_line"; //$NON-NLS-1$

	/**
	 * Marker attribute used to denote the start of the region within a Java
	 * member that the breakpoint is located within.
	 */
	private static final String MEMBER_START =  JDIDebugUIPlugin.getUniqueIdentifier() + ".member_start"; //$NON-NLS-1$

	/**
	 * Marker attribute used to denote the end of the region within a Java
	 * member that the breakpoint is located within.
	 */
	private static final String MEMBER_END =  JDIDebugUIPlugin.getUniqueIdentifier() + ".member_end"; //$NON-NLS-1$

	/**
	 * Returns the resource on which a breakpoint marker should
	 * be created for the given member. The resource returned is the
	 * associated file, or workspace root in the case of a binary in
	 * an external archive.
	 *
	 * @param member member in which a breakpoint is being created
	 * @return resource the resource on which a breakpoint marker
	 *  should be created
	 */
	public static IResource getBreakpointResource(IMember member) {
		ICompilationUnit cu = member.getCompilationUnit();
		if (cu != null && cu.isWorkingCopy()) {
			member = (IMember)member.getPrimaryElement();
		}
		IResource res = member.getResource();
		if (res == null) {
			res = ResourcesPlugin.getWorkspace().getRoot();
		}
		else if(!res.getProject().exists()) {
			res = ResourcesPlugin.getWorkspace().getRoot();
		}
		return res;
	}

	/**
	 * Returns the type that the given Java breakpoint refers to
	 *
	 * @param breakpoint Java breakpoint
	 * @return the type the breakpoint is associated with
	 */
	public static IType getType(IJavaBreakpoint breakpoint) {
		String handle = breakpoint.getMarker().getAttribute(HANDLE_ID, null);
		if (handle != null) {
			IJavaElement je = JavaCore.create(handle);
			if (je != null) {
				if (je instanceof IType) {
					return (IType)je;
				}
				if (je instanceof IMember) {
					return ((IMember)je).getDeclaringType();
				}
			}
		}
		return null;
	}

	/**
	 * Returns the member associated with the line number of
	 * the given breakpoint.
	 *
	 * @param breakpoint Java line breakpoint
	 * @return member at the given line number in the type
	 *  associated with the breakpoint
	 * @exception CoreException if an exception occurs accessing
	 *  the breakpoint
	 */
	public static IMember getMember(IJavaLineBreakpoint breakpoint) throws CoreException {
		if (breakpoint instanceof IJavaMethodBreakpoint) {
			return getMethod((IJavaMethodBreakpoint)breakpoint);
		}
		if (breakpoint instanceof IJavaWatchpoint) {
			return getField((IJavaWatchpoint)breakpoint);
		}

		int start = breakpoint.getCharStart();
		int end = breakpoint.getCharEnd();

		IType type = getType(breakpoint);

		if (start == -1 && end == -1) {
			start= breakpoint.getMarker().getAttribute(MEMBER_START, -1);
			end= breakpoint.getMarker().getAttribute(MEMBER_END, -1);
		}

		IMember member = null;
		if ((type != null && type.exists()) && (end >= start) && (start >= 0)) {
			member= binSearch(type, start, end);
		}
		if (member == null) {
			member= type;
		}
		return member;
	}

	/**
	 * Searches the given source range of the container for a member that is
	 * not the same as the given type.
	 * @param type the {@link IType}
	 * @param start the starting position
	 * @param end the ending position
	 * @return the {@link IMember} from the given start-end range
	 * @throws JavaModelException if there is a problem with the backing Java model
	 */
	protected static IMember binSearch(IType type, int start, int end) throws JavaModelException {
		IJavaElement je = getElementAt(type, start);
		if (je != null && !je.equals(type)) {
			return asMember(je);
		}
		if (end > start) {
			je = getElementAt(type, end);
			if (je != null && !je.equals(type)) {
				return asMember(je);
			}
			int mid = ((end - start) / 2) + start;
			if (mid > start) {
				je = binSearch(type, start + 1, mid);
				if (je == null) {
					je = binSearch(type, mid + 1, end - 1);
				}
				return asMember(je);
			}
		}
		return null;
	}

	/**
	 * Returns the given Java element if it is an
	 * <code>IMember</code>, otherwise <code>null</code>.
	 *
	 * @param element Java element
	 * @return the given element if it is a type member,
	 * 	otherwise <code>null</code>
	 */
	private static IMember asMember(IJavaElement element) {
		if (element instanceof IMember) {
			return (IMember)element;
		}
		return null;
	}

	/**
	 * Returns the element at the given position in the given type
	 * @param type the {@link IType}
	 * @param pos the position
	 * @return the {@link IJavaElement} at the given position
	 * @throws JavaModelException if there is a problem with the backing Java model
	 */
	protected static IJavaElement getElementAt(IType type, int pos) throws JavaModelException {
		if (type.isBinary()) {
			return type.getClassFile().getElementAt(pos);
		}
		return type.getCompilationUnit().getElementAt(pos);
	}

	/**
	 * Adds attributes to the given attribute map:<ul>
	 * <li>Java element handle id</li>
	 * <li>Attributes defined by <code>JavaCore</code></li>
	 * </ul>
	 *
	 * @param attributes the attribute map to use
	 * @param element the Java element associated with the breakpoint
	 */
	public static void addJavaBreakpointAttributes(Map<String, Object> attributes, IJavaElement element) {
		String handleId = element.getHandleIdentifier();
		attributes.put(HANDLE_ID, handleId);
		JavaCore.addJavaElementMarkerAttributes(attributes, element);
	}

	/**
	 * Adds attributes to the given attribute map:<ul>
	 * <li>Java element handle id</li>
	 * <li>Member start position</li>
	 * <li>Member end position</li>
	 * <li>Attributes defined by <code>JavaCore</code></li>
	 * </ul>
	 *
	 * @param attributes the attribute map to use
	 * @param element the Java element associated with the breakpoint
	 * @param memberStart the start position of the Java member that the breakpoint is positioned within
	 * @param memberEnd the end position of the Java member that the breakpoint is positioned within
	 */
	public static void addJavaBreakpointAttributesWithMemberDetails(Map<String, Object> attributes, IJavaElement element, int memberStart, int memberEnd) {
		addJavaBreakpointAttributes(attributes, element);
		attributes.put(MEMBER_START, new Integer(memberStart));
		attributes.put(MEMBER_END, new Integer(memberEnd));
	}

	/**
	 * Adds attributes to the given attribute map to make the
	 * breakpoint a run-to-line breakpoint:<ul>
	 * <li>PERSISTED = false</li>
	 * <li>RUN_TO_LINE = true</li>
	 * </ul>
	 *
	 * @param attributes the attribute map to use
	 */
	public static void addRunToLineAttributes(Map<String, Object> attributes) {
		attributes.put(IBreakpoint.PERSISTED, Boolean.FALSE);
		attributes.put(RUN_TO_LINE, Boolean.TRUE);
	}

	/**
	 * Returns the method associated with the method entry
	 * breakpoint.
	 *
	 * @param breakpoint Java method entry breakpoint
	 * @return method
	 */
	public static IMethod getMethod(IJavaMethodBreakpoint breakpoint) {
		String handle = breakpoint.getMarker().getAttribute(HANDLE_ID, null);
		if (handle != null) {
			IJavaElement je = JavaCore.create(handle);
			if (je != null) {
				if (je instanceof IMethod) {
					return (IMethod)je;
				}
			}
		}
		return null;
	}

	/**
	 * Returns the field associated with the watchpoint.
	 *
	 * @param breakpoint Java watchpoint
	 * @return field
	 */
	public static IField getField(IJavaWatchpoint breakpoint) {
		String handle = breakpoint.getMarker().getAttribute(HANDLE_ID, null);
		if (handle != null) {
			IJavaElement je = JavaCore.create(handle);
			if (je != null) {
				if (je instanceof IField) {
					return (IField)je;
				}
			}
		}
		return null;
	}

	/**
	 * Returns whether the given breakpoint is a run to line
	 * breakpoint
	 *
	 * @param breakpoint line breakpoint
	 * @return whether the given breakpoint is a run to line
	 *  breakpoint
	 */
	public static boolean isRunToLineBreakpoint(IJavaLineBreakpoint breakpoint) {
		return breakpoint.getMarker().getAttribute(RUN_TO_LINE, false);
	}

	/**
	 * Returns whether the given breakpoint is a compilation
	 * problem breakpoint or uncaught exception breakpoint
	 *
	 * @param breakpoint breakpoint
	 * @return whether the given breakpoint is a compilation error breakpoint or
	 *  uncaught exception breakpoint
	 */
	public static boolean isProblemBreakpoint(IBreakpoint breakpoint) {
		return breakpoint == JavaDebugOptionsManager.getDefault().getSuspendOnCompilationErrorBreakpoint() ||
			breakpoint == JavaDebugOptionsManager.getDefault().getSuspendOnUncaughtExceptionBreakpoint();
	}

	/**
     * Resolves the {@link IBreakpoint} from the given editor and ruler information. Returns <code>null</code>
     * if no breakpoint exists or the operation fails.
     *
     * @param editor the editor
     * @param info the current ruler information
     * @return the {@link IBreakpoint} from the current editor position or <code>null</code>
     * @since 3.8
     */
    public static IBreakpoint getBreakpointFromEditor(ITextEditor editor, IVerticalRulerInfo info) {
    	IAnnotationModel annotationModel = editor.getDocumentProvider().getAnnotationModel(editor.getEditorInput());
		IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
		if (annotationModel != null) {
			Iterator<Annotation> iterator = annotationModel.getAnnotationIterator();
			while (iterator.hasNext()) {
				Object object = iterator.next();
				if (object instanceof SimpleMarkerAnnotation) {
					SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) object;
					IMarker marker = markerAnnotation.getMarker();
					try {
						if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
							Position position = annotationModel.getPosition(markerAnnotation);
							int line = document.getLineOfOffset(position.getOffset());
							if (line == info.getLineOfLastMouseButtonActivity()) {
								IBreakpoint breakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
								if (breakpoint != null) {
									return breakpoint;
								}
							}
						}
					} catch (CoreException e) {
					} catch (BadLocationException e) {
					}
				}
			}
		}
		return null;
    }
}
