/*******************************************************************************
 * 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, Integer.valueOf(memberStart));
		attributes.put(MEMBER_END, Integer.valueOf(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;
    }
}
