/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jdt.internal.debug.ui.actions;


import com.ibm.icu.text.MessageFormat;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventFilter;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jface.dialogs.MessageDialog;

/**
 * Handles stepping into a selected method, for a specific thread.
 */
public class StepIntoSelectionHandler implements IDebugEventFilter {
	
	/**
	 * The method to step into
	 */
	private IMethod fMethod;
	
	/**
	 * Resolved signature of the method to step into
	 */
	private String fResolvedSignature;
	
	/**
	 * The thread in which to step
	 */
	private IJavaThread fThread;

	/**
	 * The initial stack frame
	 */
	private String fOriginalName;
	private String fOriginalSignature;
	private String fOriginalTypeName;
	private int fOriginalStackDepth;
	
	/**
	 * Whether this is the first step into.
	 */
	private boolean fFirstStep = true;
	
	/**
	 * The state of step filters before the step.
	 */
	private boolean fStepFilterEnabledState;
	
	/**
	 * Expected event kind
	 */
	private int fExpectedKind = -1;
	
	/**
	 * Expected event detail
	 */
	private int fExpectedDetail = -1;

	/**
	 * Constructs a step handler to step into the given method in the given thread
	 * starting from the given stack frame.
	 */
	public StepIntoSelectionHandler(IJavaThread thread, IJavaStackFrame frame, IMethod method) {
		fMethod = method;
		fThread = thread;
		try {
			fOriginalName = frame.getName();
			fOriginalSignature = frame.getSignature();
			fOriginalTypeName = frame.getDeclaringTypeName();
			if (method.isBinary()) {
				fResolvedSignature = method.getSignature();
			} else {
				fResolvedSignature = ToggleBreakpointAdapter.resolveMethodSignature(method.getDeclaringType(), method.getSignature());
			}
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
		}
	}
	
	/**
	 * Returns the target thread for the step.
	 * 
	 * @return the target thread for the step
	 */
	protected IJavaThread getThread() {
		return fThread;
	}
	
	protected IJavaDebugTarget getDebugTarget() {
		return (IJavaDebugTarget)getThread().getDebugTarget();
	}
	
	/**
	 * Returns the method to step into
	 * 
	 * @return the method to step into
	 */
	protected IMethod getMethod() {
		return fMethod;
	}
	
	/**
	 * Returns the resolved signature of the method to step into
	 * 
	 * @return the resolved signature of the method to step into
	 */
	protected String getSignature() {
		return fResolvedSignature;
	}	
	
	/**
	 * @see org.eclipse.debug.core.IDebugEventFilter#filterDebugEvents(org.eclipse.debug.core.DebugEvent)
	 */
	public DebugEvent[] filterDebugEvents(DebugEvent[] events) {
		// we only expect one event from our thread - find the event
		DebugEvent event = null;
		int index = -1;
		int threadEvents = 0;
		for (int i = 0; i < events.length; i++) {
			DebugEvent e = events[i];
			if (isExpectedEvent(e)) {
				event = e;
				index = i;
				threadEvents++;
			} else if (e.getSource() == getThread()) {
				threadEvents++;
			} 
		}
		
		if (event == null) {
			// nothing to process in this event set
			return events;
		}
				
		// create filtered event set
		DebugEvent[] filtered = new DebugEvent[events.length - 1];
		if (filtered.length > 0) {
			int j = 0;
			for (int i = 0; i < events.length; i++) {
				if (i != index) {
					filtered[j] = events[i];
					j++;
				}
			}
		}
		
		// if more than one event in our thread, abort (filtering our event)
		if (threadEvents > 1) {
			cleanup();
			return filtered;
		}
		
		// we have the one expected event - process it
		switch (event.getKind()) {
			case DebugEvent.RESUME:
				// next, we expect a step end
				setExpectedEvent(DebugEvent.SUSPEND, DebugEvent.STEP_END);
				if (fFirstStep) {
					fFirstStep = false;
					return events; // include the first resume event
				}
				// secondary step - filter the event
				return filtered;			
			case DebugEvent.SUSPEND:
				// compare location to desired location
				try {
					final IJavaStackFrame frame = (IJavaStackFrame)getThread().getTopStackFrame();
					int stackDepth = frame.getThread().getStackFrames().length;
					String name = null;
					if (frame.isConstructor()) {
						name = frame.getDeclaringTypeName();
						index = name.lastIndexOf('.');
						if (index >= 0) {
							name = name.substring(index + 1);
						}
					} else {
						name = frame.getName();
					}
					if (name.equals(getMethod().getElementName()) && frame.getSignature().equals(getSignature())) {
						// hit
						cleanup();
						return events;
					}
					// step again
					Runnable r = null;
					if (stackDepth > fOriginalStackDepth) {
                        if (frame.isSynthetic()) {
                            // step thru synthetic methods
                            r = new Runnable() {
                                public void run() {
                                    try {
                                        setExpectedEvent(DebugEvent.RESUME, DebugEvent.STEP_INTO);
                                        frame.stepInto();
                                    } catch (DebugException e) {
                                        JDIDebugUIPlugin.log(e);
                                        cleanup();
                                        DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(getDebugTarget(), DebugEvent.CHANGE)});
                                    }
                                }
                            };                            
                        } else {
    						r = new Runnable() {
    							public void run() {
    								try {
    									setExpectedEvent(DebugEvent.RESUME, DebugEvent.STEP_RETURN);
    									frame.stepReturn();
    								} catch (DebugException e) {
    									JDIDebugUIPlugin.log(e);
    									cleanup();
    									DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(getDebugTarget(), DebugEvent.CHANGE)});
    								}
    							}
    						};
                        }
					} else if (stackDepth == fOriginalStackDepth){
						// we should be back in the original stack frame - if not, abort
						if (!(frame.getSignature().equals(fOriginalSignature) && frame.getName().equals(fOriginalName) && frame.getDeclaringTypeName().equals(fOriginalTypeName))) {
							missed();
							return events;
						}
						r = new Runnable() {
							public void run() {
								try {
									setExpectedEvent(DebugEvent.RESUME, DebugEvent.STEP_INTO);
									frame.stepInto();	
								} catch (DebugException e) {
									JDIDebugUIPlugin.log(e);
									cleanup();
									DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(getDebugTarget(), DebugEvent.CHANGE)});
								}
							}
						};																
					} else {
						// we returned from the original frame - never hit the desired method
						missed();
						return events;								
					}
					DebugPlugin.getDefault().asyncExec(r);
					// filter the events
						return filtered;
				} catch (CoreException e) {
					// abort
					JDIDebugUIPlugin.log(e);
					cleanup();
					return events;
				}			
		}
		// execution should not reach here
		return events;
		 
	}
	
	/** 
	 * Called when stepping returned from the original frame without entering the desired method.
	 */
	protected void missed() {
		cleanup();
		Runnable r = new Runnable() {
			public void run() {
				String methodName = null;
				try {
					methodName = Signature.toString(getMethod().getSignature(), getMethod().getElementName(), getMethod().getParameterNames(), false, false);
				} catch (JavaModelException e) {
					methodName = getMethod().getElementName();
				}
				new MessageDialog(JDIDebugUIPlugin.getActiveWorkbenchShell(),  ActionMessages.StepIntoSelectionHandler_1, null, MessageFormat.format(ActionMessages.StepIntoSelectionHandler_Execution_did_not_enter____0____before_the_current_method_returned__1, new String[]{methodName}), MessageDialog.INFORMATION, new String[] {ActionMessages.StepIntoSelectionHandler_2}, 0).open();    
			}
		};
		JDIDebugUIPlugin.getStandardDisplay().asyncExec(r);		
	}

	/**
	 * Performs the step.
	 */
	public void step() {
		// add event filter and turn off step filters
		DebugPlugin.getDefault().addDebugEventFilter(this);
		fStepFilterEnabledState = getDebugTarget().isStepFiltersEnabled();
		getDebugTarget().setStepFiltersEnabled(false);
		try {
			fOriginalStackDepth = getThread().getStackFrames().length;
			setExpectedEvent(DebugEvent.RESUME, DebugEvent.STEP_INTO);
			getThread().stepInto();
		} catch (DebugException e) {
			JDIDebugUIPlugin.log(e);
			cleanup();
			DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(getDebugTarget(), DebugEvent.CHANGE)});			
		}
	}
	
	/**
	 * Cleans up when the step is complete/aborted.
	 */
	protected void cleanup() {
		DebugPlugin.getDefault().removeDebugEventFilter(this);
		// restore step filter state
		getDebugTarget().setStepFiltersEnabled(fStepFilterEnabledState);
	}
	
	/**
	 * Sets the expected debug event kind and detail we are waiting for next.
	 * 
	 * @param kind event kind
	 * @param detail event detail
	 */
	private void setExpectedEvent(int kind, int detail) {
		fExpectedKind = kind;
		fExpectedDetail = detail;
	}
	
	/**
	 * Returns whether the given event is what we expected.
	 * 
	 * @param event fire event
	 * @return whether the event is what we expected
	 */
	protected boolean isExpectedEvent(DebugEvent event) {
		return event.getSource().equals(getThread()) &&
			event.getKind() == fExpectedKind &&
			event.getDetail() == fExpectedDetail;
	}
}
