package org.eclipse.jdt.internal.debug.ui.display;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import java.io.File;
import java.text.MessageFormat;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.eval.EvaluationManager;
import org.eclipse.jdt.debug.eval.IEvaluationEngine;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JDIModelPresentation;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.IUpdate;

import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;


/**
 * Action to do simple code evaluation. The evaluation
 * is done in the UI thread and the result is inserted into the text
 * directly.
 */
public abstract class EvaluateAction extends Action implements IUpdate, IEvaluationListener, IEditorActionDelegate {
		
	protected IWorkbenchPart fWorkbenchPart;
	protected String fExpression;
	
	/**
	 * Indicates whether this action is used from within an editor.  If so,
	 * then this action is enabled only when the editor's input matches the
	 * editor input corresponding to the currently selected stack frame.
	 * If this flag is false, then this action is enabled whenever there is
	 * a stack frame selected in the UI.
	 */
	private boolean fUsedInEditor;
		
	public EvaluateAction(IWorkbenchPart workbenchPart, boolean usedInEditor) {
		super();
		fWorkbenchPart= workbenchPart;
		fUsedInEditor = usedInEditor;
	}
	
	/**
	 * Finds the currently selected stack frame in the UI
	 */
	protected IStackFrame getContext() {
		IDebugElement context = DebugUITools.getDebugContext();
		if (context != null) {
			if (context instanceof IStackFrame) {
				return (IStackFrame)context;
			}
			if (context instanceof IThread) {
				try {
					return ((IThread)context).getTopStackFrame();
				} catch (DebugException e) {
					JDIDebugUIPlugin.log(e);
				}
			}
		}
		return null;
	}
	
	/**
	 * @see Action#run()
	 */
	public void run() {
		
		fExpression= null;
		
		IStackFrame stackFrame= getContext();
		if (stackFrame == null) {
			reportError(DisplayMessages.getString("Evaluate.error.message.stack_frame_context")); //$NON-NLS-1$
			return;
		}
		
		IJavaStackFrame adapter= (IJavaStackFrame) stackFrame.getAdapter(IJavaStackFrame.class);
		if (adapter != null) {
			IJavaElement javaElement= getJavaElement(stackFrame);
			if (javaElement != null) {
				IJavaProject project = javaElement.getJavaProject();
				try {
					
					ITextSelection selection = (ITextSelection) fWorkbenchPart.getSite().getSelectionProvider().getSelection();
					fExpression= selection.getText();
					
					IDataDisplay dataDisplay= getDataDisplay();
					if (dataDisplay != null && displayExpression())
						dataDisplay.displayExpression(fExpression);
					
					IEvaluationEngine engine = getEvauationEngine((IJavaDebugTarget)adapter.getDebugTarget(), project);
					engine.evaluate(fExpression, adapter, this);
					
				} catch (CoreException e) {
					reportError(e);
				}
			} else {
				reportError(DisplayMessages.getString("Evaluate.error.message.src_context")); //$NON-NLS-1$
			}
		} else {
			reportError(DisplayMessages.getString("Evaluate.error.message.eval_adapter")); //$NON-NLS-1$
		}
	}
	
	/**
	 * Returns an evaluation engine for the given debug target
	 * and Java project.
	 * 
	 * @param vm debug target on which the evaluation will be
	 *  performed
	 * @param project the context in which the evaluation will be
	 *  compiled
	 * @exception CoreException if creation of a new evaluation
	 *  engine is required and fails 
	 */
	protected IEvaluationEngine getEvauationEngine(IJavaDebugTarget vm, IJavaProject project) throws CoreException {
		IEvaluationEngine engine = EvaluationManager.getEvaluationEngine(vm);
		if (engine == null) {
			IPath outputLocation = project.getOutputLocation();
			IWorkspace workspace = project.getProject().getWorkspace();
			IResource res = workspace.getRoot().findMember(outputLocation);
			File dir = new File(res.getLocation().toOSString());
			engine= EvaluationManager.newLocalEvaluationEngine(project, vm, dir);
		}	
		return engine;
			
	}
	
	protected IJavaElement getJavaElement(IStackFrame stackFrame) {
		
		// Get the corresponding element.
		ILaunch launch = stackFrame.getLaunch();
		if (launch == null) {
			return null;
		}
		ISourceLocator locator= launch.getSourceLocator();
		if (locator == null)
			return null;
		
		Object sourceElement = locator.getSourceElement(stackFrame);
		if (sourceElement instanceof IJavaElement) {
			return (IJavaElement) sourceElement;
		}			
		return null;
	}
	
	/**
	 * @see IUpdate#update()
	 */
	public void update() {
		boolean enabled = false;
		if (fWorkbenchPart != null && isValidStackFrame()) {
			ISelectionProvider provider = fWorkbenchPart.getSite().getSelectionProvider();
			if (provider != null)  {
				if (textHasContent(((ITextSelection)provider.getSelection()).getText())) {
					enabled = true;
				}
			}
		}
		setEnabled(enabled);
	}
	
	/**
	 * Returns true if the current stack frame context can be used for an
	 * evaluation, false otherwise.
	 */
	protected boolean isValidStackFrame() {
		IStackFrame stackFrame = getContext();
		if (stackFrame == null) {
			return false;
		}
		if (isUsedInEditor()) {
			return compareToEditorInput(stackFrame);
		} else {
			return true;
		}
	}
	
	/**
	 * Resolve an editor input from the source element of the stack frame
	 * argument, and return whether it's equal to the editor input for the
	 * editor that owns this action.
	 */
	protected boolean compareToEditorInput(IStackFrame stackFrame) {
		ILaunch launch = stackFrame.getLaunch();
		if (launch == null) {
			return false;
		}
		ISourceLocator sourceLocator = launch.getSourceLocator();
		Object sourceElement = sourceLocator.getSourceElement(stackFrame);
		JDIModelPresentation presentation = new JDIModelPresentation();
		IEditorInput sfEditorInput = presentation.getEditorInput(sourceElement);
		if (fWorkbenchPart instanceof IEditorPart) {
			return ((IEditorPart)fWorkbenchPart).getEditorInput().equals(sfEditorInput);
		}
		return false;
	}
	
	protected Shell getShell() {
		return fWorkbenchPart.getSite().getShell();
	}
	
	protected IDataDisplay getDataDisplay() {
		
		Object value= fWorkbenchPart.getAdapter(IDataDisplay.class);
		if (value instanceof IDataDisplay)
			return (IDataDisplay) value;
		
		return null;
	}	
	
	protected boolean textHasContent(String text) {
		if (text != null) {
			int length= text.length();
			if (length > 0) {
				for (int i= 0; i < length; i++) {
					if (Character.isLetterOrDigit(text.charAt(i))) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	protected void reportError(String message) {
		Status status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getPluginId(), IStatus.ERROR, message, null);
		reportError(status);
	}
	
	protected void reportError(IStatus status) {
		ErrorDialog.openError(getShell(), DisplayMessages.getString("EvaluationAction.Error_evaluating_1"), null, status); //$NON-NLS-1$
	}
	
	protected void reportError(Throwable exception) {
		if (exception instanceof DebugException) {
			DebugException de = (DebugException)exception;
			Throwable t= de.getStatus().getException();
			if (t != null) {
				reportWrappedException(t);
				return;
			}
		}
		
		if (exception instanceof CoreException) {
			CoreException ce= (CoreException) exception;
			reportError(ce.getStatus());
			return;
		}
		
		String message= MessageFormat.format(DisplayMessages.getString("Evaluate.error.message.direct_exception"), new Object[] { exception.getClass() }); //$NON-NLS-1$
		if (exception.getMessage() != null)
			message= MessageFormat.format(DisplayMessages.getString("Evaluate.error.message.exception.pattern"), new Object[] { message, exception.getMessage() }); //$NON-NLS-1$
		reportError(message);
	}
	
	protected void reportProblems(IEvaluationResult result) {
		IMarker[] problems= result.getProblems();
		if (problems.length == 0)
			reportError(result.getException());
		else
			reportProblems(problems);
	}
	
	protected void reportProblems(IMarker[] problems) {
		
		String defaultMsg= DisplayMessages.getString("Evaluate.error.message.unqualified_error"); //$NON-NLS-1$
		
		String message= ""; //$NON-NLS-1$
		for (int i= 0; i < problems.length; i++) {
			IMarker problem= problems[i];
			if (problem.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
				String msg= problems[i].getAttribute(IMarker.MESSAGE, defaultMsg);
				if (i == 0) {
					message= msg;
				} else {
					message= MessageFormat.format(DisplayMessages.getString("Evaluate.error.problem_append_pattern"), new Object[] { message, msg }); //$NON-NLS-1$
				}
			}
		}
		
		if (message.length() != 0) {
			reportError(message);
		}
	}
	
	protected void reportWrappedException(Throwable exception) {
		if (exception instanceof com.sun.jdi.InvocationException) {
			InvocationException ie= (InvocationException) exception;
			ObjectReference ref= ie.exception();
			reportError(MessageFormat.format(DisplayMessages.getString("Evaluate.error.message.wrapped_exception"), new Object[] { ref.referenceType().name() })); //$NON-NLS-1$
		} else
			reportError(exception);
	}
	
	/**
	 * Returns whether to display the expression via
	 * the data display.
	 */
	protected boolean displayExpression() {
		return true;
	}
	
	protected boolean isUsedInEditor() {
		return fUsedInEditor;
	}
	
	/**
	 * @see IEditorActionDelegate#setActiveEditor(IAction, IEditorPart)
	 */
	public void setActiveEditor(IAction action, IEditorPart targetEditor) {
		fWorkbenchPart = targetEditor;
		update();
		action.setEnabled(isEnabled());
	}

	/**
	 * @see IActionDelegate#run(IAction)
	 */
	public void run(IAction action) {
		run();
	}

	/**
	 * @see IActionDelegate#selectionChanged(IAction, ISelection)
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		update();
		action.setEnabled(isEnabled());
	}	
}
