/*******************************************************************************
 * Copyright (c) 2010, 2011 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.wst.jsdt.debug.internal.ui.breakpoints;

import java.util.HashMap;

import org.eclipse.core.resources.IFile;
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.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.jsdt.core.IClassFile;
import org.eclipse.wst.jsdt.core.IFunction;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IMember;
import org.eclipse.wst.jsdt.core.ISourceRange;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.ITypeRoot;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptFunctionBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptLineBreakpoint;
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
import org.eclipse.wst.jsdt.debug.internal.ui.DebugWCManager;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.javaeditor.ASTProvider;

/**
 * JavaScript adapter for toggling breakpoints in the JSDT editor
 * 
 * @since 1.0
 */
public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtension {
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#canToggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
		return selection instanceof ITextSelection;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
		return selection instanceof ITextSelection;
	}

	/**
	 * Toggles a line breakpoint 
	 * @param part
	 * @param selection
	 * @param element
	 */
	void toggleLineBreakpoint(final IWorkbenchPart part, final ITextSelection selection, final IJavaScriptElement element, final int linenumber) {
		Job job = new Job("Toggle Line Breakpoints") { //$NON-NLS-1$
            protected IStatus run(IProgressMonitor monitor) {
            	try {
            		ITextEditor editor = getTextEditor(part);
					if(editor != null && part instanceof IEditorPart) {
						if(element == null) {
							reportToStatusLine(part, Messages.failed_line_bp_no_element);
							return Status.CANCEL_STATUS;
						}
						IResource resource = element.getResource();
						if(resource == null) {
							reportToStatusLine(part, NLS.bind(Messages.failed_line_bp_no_resource, element.getElementName()));
							return Status.CANCEL_STATUS;
						}
						IBreakpoint bp = lineBreakpointExists(resource, linenumber);
						if(bp != null) {
							DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(bp, true);
							return Status.OK_STATUS;
						}
						IDocumentProvider documentProvider = editor.getDocumentProvider();
						IDocument document = documentProvider.getDocument(editor.getEditorInput());
						int charstart = -1, charend = -1;
						try {
							IRegion line = document.getLineInformation(linenumber - 1);
							charstart = line.getOffset();
							charend = charstart + line.getLength();
						}
						catch (BadLocationException ble) {}
						HashMap attributes = new HashMap();
						attributes.put(IJavaScriptBreakpoint.TYPE_NAME, getTypeName(element));
						attributes.put(IJavaScriptBreakpoint.SCRIPT_PATH, getScriptPath(element));
						attributes.put(IJavaScriptBreakpoint.ELEMENT_HANDLE, element.getHandleIdentifier());
						JavaScriptDebugModel.createLineBreakpoint(resource, linenumber, charstart, charend, attributes, true);
						return Status.OK_STATUS;
					}
					reportToStatusLine(part, Messages.failed_to_create_line_bp);
					return Status.CANCEL_STATUS;
	            }
	        	catch(CoreException ce) {
	        		return ce.getStatus();
        		}
        	}
		};
		job.setPriority(Job.INTERACTIVE);
        job.setSystem(true);
        job.schedule();
	}
	
	/**
	 * Callback from {@link JavaScriptHtmlBreakpointProvider}
	 * @param resource
	 * @param document
	 * @param linenumber
	 * @throws CoreException
	 */
	void addBreakpoint(IResource resource, IDocument document, int linenumber) throws CoreException {
		IBreakpoint bp = lineBreakpointExists(resource, linenumber);
		if(bp != null) {
			DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(bp, true);
		}
		int charstart = -1, charend = -1;
		try {
			IRegion line = document.getLineInformation(linenumber - 1);
			charstart = line.getOffset();
			charend = charstart + line.getLength();
		}
		catch (BadLocationException ble) {}
		HashMap attributes = new HashMap();
		attributes.put(IJavaScriptBreakpoint.TYPE_NAME, null);
		attributes.put(IJavaScriptBreakpoint.SCRIPT_PATH, resource.getFullPath().makeAbsolute().toString());
		attributes.put(IJavaScriptBreakpoint.ELEMENT_HANDLE, null);
		JavaScriptDebugModel.createLineBreakpoint(resource, linenumber, charstart, charend, attributes, true);
	}
	
	/**
	 * Returns the path to the script in the workspace or the name of the script in the event it is
	 * and external or virtual script
	 * @param element
	 * @return the path to the script 
	 */
	String getScriptPath(IJavaScriptElement element) {
		IPath path = element.getPath();
		return path.makeAbsolute().toString();
	}
	
	/**
	 * Resolves the type name from the given element
	 * @param element
	 * @return
	 */
	String getTypeName(IJavaScriptElement element) {
		switch(element.getElementType()) {
			case IJavaScriptElement.TYPE: {
				return ((IType)element).getFullyQualifiedName();
			}
			case IJavaScriptElement.METHOD:
			case IJavaScriptElement.FIELD: {
				IMember member = (IMember) element;
				IType type = member.getDeclaringType();
				if(type != null) {
					return type.getFullyQualifiedName();
				}
			}
			//$FALL-THROUGH$
			default: {
				return null;
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public void toggleLineBreakpoints(final IWorkbenchPart part, final ISelection selection) throws CoreException {
		//do nothing
	}
	
	/**
	 * Resolves the declaring type for the member
	 * @param member
	 * @return the declaring type for the member
	 */
	IType resolveType(IJavaScriptElement element) {
		switch(element.getElementType()) {
			case IJavaScriptElement.TYPE: {
				return (IType) element;
			}
			case IJavaScriptElement.METHOD:
			case IJavaScriptElement.FIELD: {
				IMember member = (IMember) element;
				IType type = member.getDeclaringType();
				if(type == null) {
					ITypeRoot root = (ITypeRoot) member.getParent();
					type = root.findPrimaryType();
				}
				return type;
			}
			default: {
				//already a type root
				if(element instanceof ITypeRoot) {
					return ((ITypeRoot)element).findPrimaryType();
				}
			}
		}
		return null;
	}
	
	/**
	 * Resolves the region from the given document and tries to parse the text of the region. Returns the {@link JavaScriptUnit}
	 * representing the region or <code>null</code> if it could not be computed
	 * 
	 * @param doc
	 * @param offset
	 * @return the {@link JavaScriptUnit} for the region from the document or <code>null</code>
	 */
	JavaScriptUnit parse(IDocument doc, int offset) {
		try {
			ITypedRegion region = doc.getPartition(offset);
			if(region != null) {
				ASTParser parser = ASTParser.newParser(AST.JLS3);
				//parser.setKind(ASTParser.K_STATEMENTS);
				parser.setSource(doc.get(offset, region.getLength()).toCharArray());
				return (JavaScriptUnit)parser.createAST(null);
			}
		}
		catch(BadLocationException ble) {
			//do nothing, return null
		}
		return null;
	}
	
	/**
	 * 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 element member in which a breakpoint is being created
	 * @return resource the resource on which a breakpoint marker
	 *  should be created
	 */
	IResource getBreakpointResource(IJavaScriptElement element) {
		IResource res = element.getResource();
		if (res == null) {
			res = ResourcesPlugin.getWorkspace().getRoot();
		}
		else if(!res.getProject().exists()) {
			res = ResourcesPlugin.getWorkspace().getRoot();
		}
		return res;
	}
	
	/**
	 * Returns the {@link ITypeRoot} for the given editor input
	 * @param input
	 * @return the {@link ITypeRoot} for the editor input or <code>null</code>
	 */
	ITypeRoot getTypeRoot(IEditorInput input) {
		ITypeRoot root = (ITypeRoot) input.getAdapter(IClassFile.class);
		if(root == null) {
			root = DebugWCManager.getCompilationUnit(input, false);
		}
		return root;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
		return selection instanceof ITextSelection;
	}
	
	/**
	 * Delegate for toggling a method breakpoint
	 * @param part
	 * @param element
	 * @param line
	 */
	void toggleMethodBreakpoint(final IWorkbenchPart part, final IJavaScriptElement element, final int line) {
		Job job = new Job("Toggle Function Breakpoints") { //$NON-NLS-1$
            protected IStatus run(IProgressMonitor monitor) {
            	try {
					if(element == null) {
						reportToStatusLine(part, Messages.failed_function_bp_no_element);
						return Status.CANCEL_STATUS;
					}
					if(element.getElementType() == IJavaScriptElement.METHOD) {
						IFunction method = (IFunction) element;
						IResource resource = element.getResource();
						if(resource == null) {
							reportToStatusLine(part, NLS.bind(Messages.failed_function_bp_no_resource, element.getElementName()));
							return Status.CANCEL_STATUS;
						}
						IBreakpoint bp = methodBreakpointExists(resource, method.getElementName(), method.getSignature());
						if(bp != null) {
							DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(bp, true);
							return Status.OK_STATUS;
						}
						ISourceRange range = method.getNameRange();
						int start = -1, end = -1;
						if(range != null) {
							start = range.getOffset();
							end = start + range.getLength();
						}
						HashMap attributes = new HashMap();
						//hack if the type is null the member is declared in a top-level type
						//nothing else we can do
						attributes.put(IJavaScriptBreakpoint.TYPE_NAME, getTypeName(element));
						attributes.put(IJavaScriptBreakpoint.SCRIPT_PATH, getScriptPath(element));
						attributes.put(IMarker.LINE_NUMBER, new Integer(line));
						IJavaScriptFunctionBreakpoint breakpoint = JavaScriptDebugModel.createFunctionBreakpoint(resource, method.getElementName(), method.getSignature(), start, end, attributes, true);
						breakpoint.setJavaScriptElementHandle(element.getHandleIdentifier());
						return Status.OK_STATUS;
					}
					reportToStatusLine(part, Messages.failed_to_create_function_bp);
				}
	        	catch(CoreException ce) {
	        		return ce.getStatus();
        		}
	        	return Status.CANCEL_STATUS;
        	}
		};
		job.setPriority(Job.INTERACTIVE);
        job.setSystem(true);
        job.schedule();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public void toggleMethodBreakpoints(final IWorkbenchPart part, final ISelection selection) throws CoreException {
		//do nothing
	}

	/**
	 * Sends a friendly message to the status line about why we could not set a breakpoint
	 * @param part
	 * @param message
	 */
	void reportToStatusLine(final IWorkbenchPart part, final String message) {
		getStandardDisplay().asyncExec(new Runnable() {
            public void run() {
				IEditorStatusLine statusLine = (IEditorStatusLine) part.getAdapter(IEditorStatusLine.class);
		        if (statusLine != null) {
		            if (message != null) {
		                statusLine.setMessage(true, message, null);
		            } else {
		                statusLine.setMessage(true, null, null);
		            }
		        }
            }
		});
	}
	
	/**
	 * Returns the standard display to be used. 
	 */
	Display getStandardDisplay() {
		Display display;
		display = Display.getCurrent();
		if (display == null) {
			display = Display.getDefault();
		}
		return display;		
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#toggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
		if(selection instanceof ITextSelection) {
			ITextEditor textEditor = getTextEditor(part);
			if(textEditor == null) {
				reportToStatusLine(part, Messages.no_editor_could_be_found);
				return;
			}
			ITypeRoot root = getTypeRoot(textEditor.getEditorInput());
            if(root instanceof IJavaScriptUnit) {
            	IJavaScriptUnit unit = (IJavaScriptUnit) root;
                synchronized (unit) {
                    unit.reconcile(IJavaScriptUnit.NO_AST , false, null, null);
                }
            }
            if(root == null) {
            	reportToStatusLine(part, Messages.type_root_could_not_be_computed);
            	return;
            }
			JavaScriptUnit jsunit = JavaScriptPlugin.getDefault().getASTProvider().getAST(root, ASTProvider.WAIT_YES, null);
			BreakpointLocationFinder finder = new BreakpointLocationFinder(jsunit, ((TextSelection)selection).getStartLine()+1, false);
			jsunit.accept(finder);
			switch(finder.getLocation()) {
				case BreakpointLocationFinder.UNKNOWN : {
					reportToStatusLine(part, Messages.no_valid_location);
					return;
				}
				case BreakpointLocationFinder.LINE: {
					IJavaScriptElement element = root.getElementAt(finder.getOffset());
					if(element == null) {
						element = root;
					}
					toggleLineBreakpoint(part, (ITextSelection) selection, element, finder.getLineNumber());
					return;
				}
				case BreakpointLocationFinder.FUNCTION: {
					toggleMethodBreakpoint(part, root.getElementAt(finder.getOffset()), finder.getLineNumber());
					return;
				}
			}
		}
		else {
			IStructuredSelection ss = (IStructuredSelection) selection;
        	Object o = ss.getFirstElement();
        	if(o instanceof IMember) {
        		IMember member = (IMember) o;
        		if(member.getElementType() == IJavaScriptElement.METHOD) {
    				toggleMethodBreakpoint(part, member, -1);
    			}
        	}
		}
	}
	
	/**
	 * Returns if a line breakpoint exists on the given line in the given resource
	 * @param resource
	 * @param linenumber
	 * @return true if a line breakpoint exists on the given line in the given resource, false otherwise
	 */
	IBreakpoint lineBreakpointExists(IResource resource, int linenumber) {
		IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JavaScriptDebugModel.MODEL_ID);
		IJavaScriptLineBreakpoint breakpoint = null;
		for (int i = 0; i < breakpoints.length; i++) {
			if(breakpoints[i] instanceof IJavaScriptLineBreakpoint) {
				breakpoint = (IJavaScriptLineBreakpoint) breakpoints[i];
				try {
					if(IJavaScriptLineBreakpoint.MARKER_ID.equals(breakpoint.getMarker().getType()) &&
						resource.equals(breakpoint.getMarker().getResource()) &&
						linenumber == breakpoint.getLineNumber()) {
						return breakpoint;
					}
				} catch (CoreException e) {}
			}
		}
		return null;
	}
	
	/**
	 * Returns if a method breakpoint exists with the given name and signature in the given resource
	 * @param resource
	 * @param name
	 * @param signature
	 * @return true if a method breakpoint exists with the given name and signature in the given resource, false otherwise
	 */
	IBreakpoint methodBreakpointExists(IResource resource, String name, String signature) {
		IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JavaScriptDebugModel.MODEL_ID);
		IJavaScriptBreakpoint breakpoint = null;
		for (int i = 0; i < breakpoints.length; i++) {
			breakpoint = (IJavaScriptBreakpoint) breakpoints[i];
			try {
				if(IJavaScriptFunctionBreakpoint.MARKER_ID.equals(breakpoint.getMarker().getType()) &&
					resource.equals(breakpoint.getMarker().getResource()) &&
					name.equals(breakpoint.getMarker().getAttribute(IJavaScriptFunctionBreakpoint.FUNCTION_NAME)) &&
					signature.equals(breakpoint.getMarker().getAttribute(IJavaScriptFunctionBreakpoint.FUNCTION_SIGNAURE))) {
					return breakpoint;
				}
			} catch (CoreException e) {}
		}
		return null;
	}
	
	/**
     * Returns the resource associated with the specified editor part
     * @param editor the currently active editor part
     * @return the corresponding <code>IResource</code> from the editor part
     */
    IResource getResource(IEditorPart editor) {
        IEditorInput editorInput = editor.getEditorInput();
        IResource resource = (IResource) editorInput.getAdapter(IFile.class);
        if (resource == null) {
            resource = ResourcesPlugin.getWorkspace().getRoot();
        }
        return resource;
    }
	
    /**
     * Returns the text editor associated with the given part or <code>null</code>
     * if none. In case of a multi-page editor, this method should be used to retrieve
     * the correct editor to perform the breakpoint operation on.
     * 
     * @param part workbench part
     * @return text editor part or <code>null</code>
     */
    ITextEditor getTextEditor(IWorkbenchPart part) {
    	if (part instanceof ITextEditor) {
    		return (ITextEditor) part;
    	}
    	return (ITextEditor) part.getAdapter(ITextEditor.class);
    }
    
	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {}
}
