package org.eclipse.jdt.internal.debug.core;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import com.sun.jdi.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.IDebugStatusConstants;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.eval.IEvaluationContext;
import org.eclipse.jdt.debug.core.*;
import java.util.*;

/**
 * Proxy to a stack frame on the target.
 */

public class JDIStackFrame extends JDIDebugElement implements IJavaStackFrame {

	// Resource String keys
	private static final String PREFIX= "jdi_stack_frame.";
	private static final String ERROR= PREFIX + "error.";
	private static final String ERROR_GET_NAME= ERROR + "get_name";
	private static final String ERROR_DROP_NOT_SUPPORTED= ERROR + "drop_not_supported";
	private static final String ERROR_GET_ARGUMENTS= ERROR + "get_arguments";
	private static final String ERROR_GET_DECLARING_TYPE= ERROR + "get_declaring_type";
	private static final String ERROR_GET_RECEIVING_TYPE= ERROR + "get_receiving_type";
	private static final String ERROR_GET_LINE_NUMBER= ERROR + "get_line_number";
	private static final String ERROR_GET_SIGNATURE= ERROR + "get_signature";
	private static final String ERROR_GET_METHOD= ERROR + "get_method";
	private static final String ERROR_GET_SOURCE_NAME= ERROR + "get_source_name";

	/**
	 * Underlying stack frame
	 */
	protected StackFrame fStackFrame;
	
	/**
	 * The method this stack frame is associated with. Cached
	 * lazily on first access.
	 */
	protected Method fMethod= null;
	
	/**
	 * Whether the variables need refreshing
	 */
	protected boolean fRefreshVariables= true;

	/**
	 * Creates a new stack frame in the given thread.
	 */
	public JDIStackFrame(JDIThread thread, StackFrame stackFrame) {
		super(thread);
		fStackFrame= stackFrame;
	}

	/**
	 * @see IDebugElement
	 */
	public int getElementType() {
		return STACK_FRAME;
	}
	
	/**
	 * @see IDebugElement
	 */
	public IStackFrame getStackFrame() {
		return this;
	}
	
	/**
	 * @see IDebugElement
	 */
	public IThread getThread() {
		return (IThread)fParent;
	}

	/**
	 * @see ISuspendResume
	 */
	public boolean canResume() {
		return getThread().canResume();
	}

	/**
	 * @see ISuspendResume
	 */
	public boolean canSuspend() {
		return getThread().canSuspend();
	}

	/**
	 * @see IStep.
	 */
	public boolean canStepInto() {
		try {
			return exists() && isTopStackFrame() && getThread().canStepInto();
		} catch (DebugException e) {
			return false;
		}
	}

	/**
	 * @see IStep.
	 */
	public boolean canStepOver() {
		try {
			return exists() && getThread().canStepOver();
		} catch (DebugException e) {
			return false;
		}
	}

	/**
	 * @see IStep.
	 */
	public boolean canStepReturn() {
		try {
			List frames = ((JDIThread)getThread()).getChildren0();
			if (frames != null && !frames.isEmpty()) {
				Object bottomFrame = frames.get(frames.size() - 1);
				return exists() && !this.equals(bottomFrame) && getThread().canStepReturn();
			}
		} catch (DebugException e) {
		}
		return false;
	}

	/**
	 * Returns the underlying method associated with this stack frame.
	 */
	Method getUnderlyingMethod() throws DebugException {
		if (fMethod == null) {
			try {
				fMethod= fStackFrame.location().method();
			} catch (RuntimeException e) {
				targetRequestFailed(ERROR_GET_METHOD, e);
			}
		}
		return fMethod;
	}

	/**
	 * @see IDebugElement
	 */
	protected List getChildren0() throws DebugException {
		if (fChildren == null) {
			Method method= getUnderlyingMethod();
			fChildren= new ArrayList();
			// #isStatic() does not claim to throw any exceptions - so it is not try/catch coded
			if (method.isStatic()) {
				// add statics
				List allFields= null;
				try {
					allFields= method.declaringType().allFields();
				} catch (VMDisconnectedException e) {
					return Collections.EMPTY_LIST;
				} catch (RuntimeException e) {
					targetRequestFailed(ERROR_GET_CHILDREN, e);
				}
				if (allFields != null) {
					Iterator fields= allFields.iterator();
					while (fields.hasNext()) {
						Field field= (Field) fields.next();
						if (field.isStatic()) {
							fChildren.add(new JDIFieldVariable(this, field));
						}
					}
					Collections.sort(fChildren, new Comparator() {
						public int compare(Object a, Object b) {
							return sortStaticChildren(a, b);
						}
					});
				}
			} else {
				// add "this"
				ObjectReference t= null;
				try {
					t= fStackFrame.thisObject();
				} catch (VMDisconnectedException e) {
					return Collections.EMPTY_LIST;
				} catch (RuntimeException e) {
					targetRequestFailed(ERROR_GET_CHILDREN, e);
				}
				if (t != null) {
					fChildren.add(new JDIThisVariable(this, t));
				}
			}
			// add locals
			Iterator variables= getUnderlyingVisibleVariables().iterator();
			while (variables.hasNext()) {
				LocalVariable var= (LocalVariable) variables.next();
				fChildren.add(new JDILocalVariable(this, var));
			}
		} else if (fRefreshVariables) {
			updateVariables();
		}
		fRefreshVariables = false;
		return fChildren;
	}

	/**
	 * Sorts the static variable children lexically
	 */
	protected int sortStaticChildren(Object a, Object b) {
		JDIFieldVariable v1= (JDIFieldVariable)a;
		JDIFieldVariable v2= (JDIFieldVariable)b;
		try {
			return v1.getName().compareToIgnoreCase(v2.getName());
		} catch (DebugException de) {
			internalError(de);
			return -1;
		}
	}
	/**
	 * @see IDebugElement
	 */
	public String getName() throws DebugException {
		return getMethodName();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public List getArgumentTypeNames() throws DebugException {
		try {
			return getUnderlyingMethod().argumentTypeNames();
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_ARGUMENTS, e);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @see IStackFrame
	 */
	public int getLineNumber() throws DebugException {
		if (getThread().isSuspended()) {
			try {
				Location location= fStackFrame.location();
				if (location != null) {
					return location.lineNumber();
				}
			} catch (VMDisconnectedException e) {
			} catch (RuntimeException e) {
				targetRequestFailed(ERROR_GET_LINE_NUMBER, e);
			}
		}
		return -1;
	}

	/**
	 * @see IStep
	 */
	public boolean isStepping() {
		return getThread().isStepping();
	}

	/**
	 * @see ISuspendResume
	 */
	public boolean isSuspended() {
		return getThread().isSuspended();
	}

	/**
	 * @see ISuspendResume
	 */
	public void resume() throws DebugException {
		getThread().resume();
	}

	/**
	 * @see IStep.
	 */
	public void stepInto() throws DebugException {
		if (!canStepInto()) {
			return;
		}
		getThread().stepInto();
	}

	/**
	 * @see IStep
	 */
	public void stepOver() throws DebugException {
		if (!canStepOver()) {
			return;
		}
		if (isTopStackFrame()) {
			getThread().stepOver();
		} else {
			((JDIThread)getThread()).stepToFrame(this);
		}
	}

	/**
	 * @see IStep
	 */
	public void stepReturn() throws DebugException {
		if (!canStepReturn()) {
			return;
		}
		if (isTopStackFrame()) {
			getThread().stepReturn();
		} else {
			List frames = ((JDIThread)getThread()).getChildren0();
			int index = frames.indexOf(this);
			if (index >= 0 && index < frames.size() - 1) {
				IStackFrame nextFrame = (IStackFrame)frames.get(index + 1);
				((JDIThread)getThread()).stepToFrame(nextFrame);
			}
		}
	}

	/**
	 * @see ISuspendResume
	 */
	public void suspend() throws DebugException {
		getThread().suspend();
	}

	/**
	 * Notes that variables will need to be updated on
	 * the next access.
	 */
	protected void invalidateVariables() {
		fRefreshVariables = true;
	}
	
	/**
	 * Update my variables incrementally.
	 */
	protected void updateVariables() throws DebugException {
		if (fChildren == null) {
			return;
		}

		Method method= getUnderlyingMethod();
		int index= 0;
		if (method.isStatic()) {
			// update statics
			while (index < fChildren.size() && fChildren.get(index) instanceof JDIFieldVariable) {
				index++;
			}
		} else {
			// update "this"
			ObjectReference thisObject= null;
			try {
				thisObject= fStackFrame.thisObject();
			} catch (VMDisconnectedException e) {
				return;
			} catch (RuntimeException e) {
				targetRequestFailed(ERROR_GET_CHILDREN, e);
			}
			JDIThisVariable oldThisObject= null;
			if (!fChildren.isEmpty() && fChildren.get(0) instanceof JDIThisVariable) {
				oldThisObject= (JDIThisVariable) fChildren.get(0);
			}
			if (thisObject == null && oldThisObject != null) {
				// removal of 'this'
				fChildren.remove(0);
				index= 0;
			} else {
				if (oldThisObject == null && thisObject != null) {
					// creation of 'this'
					oldThisObject= new JDIThisVariable(this, thisObject);
					fChildren.add(0, oldThisObject);
					index= 1;
				} else {
					if (oldThisObject != null) {
						// 'this' still exists
						index= 1;
					}
				}
			}
		}

		List locals= null;
		try {
			locals= fStackFrame.visibleVariables();
		} catch (AbsentInformationException e) {
			locals= new ArrayList(0);
		} catch (NativeMethodException e) {
			locals= new ArrayList(0);
		} catch (VMDisconnectedException e) {
			return;
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_CHILDREN, e);
		}
		int localIndex= -1;
		while (index < fChildren.size()) {
			JDILocalVariable local= (JDILocalVariable) fChildren.get(index);
			localIndex= locals.indexOf(local.getLocal());
			if (localIndex >= 0) {
				// update variable with new underling JDI LocalVariable
				local.setLocal((LocalVariable) locals.get(localIndex));
				locals.remove(localIndex);
				index++;
			} else {
				// remove variable
				fChildren.remove(index);
			}
		}

		// add any new locals
		Iterator newOnes= locals.iterator();
		while (newOnes.hasNext()) {
			JDILocalVariable local= new JDILocalVariable(this, (LocalVariable) newOnes.next());
			fChildren.add(local);
		}
	}

	/**
	 * @see IDropToFrame
	 */
	public boolean supportsDropToFrame() {
		try {
			JDIThread thread= (JDIThread) getThread();
			return !thread.isTerminated()
				&& thread.isSuspended()
				&& thread.getUnderlyingThread() instanceof org.eclipse.jdi.hcr.ThreadReference
				&& ((org.eclipse.jdi.hcr.VirtualMachine) ((JDIDebugTarget) getDebugTarget()).getVM()).canDoReturn(); 
		} catch (UnsupportedOperationException e) {
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			internalError(e);
		}
		return false;
	}

	/**
	 * @see IDropToFrame
	 */
	public void dropToFrame() throws DebugException {
		if (supportsDropToFrame()) {
			((JDIThread) getThread()).dropToFrame(this);
		} else {
			notSupported(ERROR_DROP_NOT_SUPPORTED);
		}
	}

	/**
	 * @see IVariableLookup
	 */
	public IVariable findVariable(String varName) throws DebugException {
		List list= getChildren0();
		Iterator variables = list.iterator();
		JDIThisVariable thisVariable= null;
		while (variables.hasNext()) {
			IVariable var= (IVariable) variables.next();
			if (var.getName().equals(varName)) {
				return var;
			}
			if (var instanceof JDIThisVariable) {
				// save for later - check for instance and static vars
				thisVariable= (JDIThisVariable)var;
			}
		}

		if (thisVariable != null) {
			variables= ((JDIValue)thisVariable.getValue()).getChildren0().iterator();
			while (variables.hasNext()) {
				IVariable var= (IVariable) variables.next();
				if (var.getName().equals(varName)) {
					return var;
				}
			}
		}

		return null;

	}

	/**
	 * Helper method that retrieves visible varialbes in this stack frame
	 * handling any exceptions. Returns an empty list if there are no
	 * variables.
	 */
	List getUnderlyingVisibleVariables() throws DebugException {
		List variables= Collections.EMPTY_LIST;
		try {
			variables= fStackFrame.visibleVariables();
		} catch (AbsentInformationException e) {
		} catch (NativeMethodException e) {
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_CHILDREN, e);
		}

		return variables;
	}

	/**
	 * Returns the underlying JDI StackFrame
	 */
	StackFrame getUnderlyingStackFrame() {
		return fStackFrame;
	}
	
	/**
	 * Sets the underlying JDI StackFrame. Called by a thread
	 * when incrementally updating after a step has completed.
	 */
	void setUnderlyingStackFrame(StackFrame frame) {
		fStackFrame = frame;
	}

	
	/**
	 * Returns the Java stack frame adapter for this stack frame
	 * 
	 * @see IAdaptable
	 */
	protected Object getAdpater(Class adapter) {
		if (adapter == IJavaStackFrame.class || adapter == IJavaModifiers.class) {
			return this;
		}
		return super.getAdapter(adapter);
	}

	/**
	 * Evaluates the snippet in the context of this stack frame
	 *
	 * @see IJavaStackFrame
	 */
	public void evaluate(String snippet, IJavaEvaluationListener listener, IJavaProject project) throws DebugException {
		IEvaluationContext underlyingContext = ((JDIDebugTarget)getDebugTarget()).getEvaluationContext(project);
		evaluate(snippet, listener, underlyingContext);
	}

	/**
	 * @see IJavaStackFrame
	 */
	public void evaluate(String snippet, IJavaEvaluationListener listener, IEvaluationContext evaluationContext) throws DebugException {
		((JDIThread)getThread()).verifyEvaluation(evaluationContext);
		StackFrameEvaluationContext context = new StackFrameEvaluationContext(this, evaluationContext);
		context.evaluate(snippet, listener);
	}	
	
	/**
	 * @see IJavaEvaluate
	 */
	public boolean canPerformEvaluation() {
		return ((IJavaThread)getThread()).canPerformEvaluation();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public String getSignature() throws DebugException {
		try {
			return getUnderlyingMethod().signature();
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_SIGNATURE, e);
		}
		return getUnknownMessage();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public String getDeclaringTypeName() throws DebugException {
		try {
			return getUnderlyingMethod().declaringType().name();
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_DECLARING_TYPE, e);
		}
		return getUnknownMessage();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public String getReceivingTypeName() throws DebugException {
		try {
			ObjectReference thisObject = fStackFrame.thisObject();
			if (thisObject == null) {
				return getDeclaringTypeName();
			} else {
				return thisObject.referenceType().name();
			}
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_RECEIVING_TYPE, e);
		}
		return getUnknownMessage();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public String getMethodName() throws DebugException {
		try {
			return getUnderlyingMethod().name();	
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_NAME, e);
		}
		return getUnknownMessage();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isAbstract() throws DebugException {
		return getUnderlyingMethod().isAbstract();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isNative() throws DebugException {
		return getUnderlyingMethod().isNative();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isStaticInitializer() throws DebugException {
		return getUnderlyingMethod().isStaticInitializer();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isFinal() throws DebugException {
		return getUnderlyingMethod().isFinal();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isSynchronized() throws DebugException {
		return getUnderlyingMethod().isSynchronized();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isSynthetic() throws DebugException {
		return getUnderlyingMethod().isSynthetic();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isPublic() throws DebugException {
		return getUnderlyingMethod().isPublic();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isPrivate() throws DebugException {
		return getUnderlyingMethod().isPrivate();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isProtected() throws DebugException {
		return getUnderlyingMethod().isProtected();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isPackagePrivate() throws DebugException {
		return getUnderlyingMethod().isPackagePrivate();
	}
	
	/**
	 * @see IJavaStackFrame
	 */
	public boolean isStatic() throws DebugException {
		return getUnderlyingMethod().isStatic();
	}
		
	/**
	 * @see IJavaStackFrame
	 */
	public String getSourceName() throws DebugException {
		try {
			Location l = getUnderlyingMethod().location();
			if (l != null) {
				return l.sourceName();
			}
		} catch (AbsentInformationException e) {
		} catch (VMDisconnectedException e) {
		} catch (RuntimeException e) {
			targetRequestFailed(ERROR_GET_SOURCE_NAME, e);
		}
		return null;
	}
	
	protected boolean isTopStackFrame() throws DebugException {
		IStackFrame tos = getThread().getTopStackFrame();
		return tos != null && tos.equals(this);
	}
	
	protected boolean exists() throws DebugException {
		return ((JDIThread)getThread()).getChildren0().indexOf(this) != -1;
	}
}


