/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.eval;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jdt.core.tests.runtime.RuntimeConstants;
import org.eclipse.jdt.internal.eval.EvaluationConstants;
import org.eclipse.jdt.internal.eval.EvaluationResult;
import org.eclipse.jdt.internal.eval.InstallException;

import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.InvocationException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequest;

public class JDIStackFrame implements EvaluationConstants, RuntimeConstants {
	VirtualMachine jdiVM;
	ThreadReference jdiThread;
	String userCode;
	String breakpointClassName;
	String breakpointMethodName;
	int breakpointLine;
public JDIStackFrame(VirtualMachine jdiVM, DebugEvaluationTest test, String userCode) {
	this(jdiVM, test, userCode, "_JDIStackFrame_", "foo", Integer.MAX_VALUE);
}
public JDIStackFrame(
	VirtualMachine jdiVM, 
	DebugEvaluationTest test, 
	String userCode,
	String breakpointClassName,
	String breakpointMethodName,
	int breakpointLine) {
		
	this.jdiVM = jdiVM;
	this.userCode = userCode;
	this.breakpointClassName = breakpointClassName;
	this.breakpointMethodName = breakpointMethodName;
	this.breakpointLine = breakpointLine;
	
	test.jdiStackFrame = null;
	this.jdiThread = this.getDebuggedThread(test);
	test.jdiStackFrame = this;
}
public char[] declaringTypeName() {
	if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet
		StackFrame frame = getStackFrame();
		return frame.location().declaringType().name().toCharArray();
	}
	return null;
}
protected ThreadReference getDebuggedThread(DebugEvaluationTest test) {
	try {
		// desintall previous breakpoints
		this.jdiVM.eventRequestManager().deleteAllBreakpoints();

		// install a breakpoint at the breakpointLine
		List classes = this.jdiVM.classesByName(this.breakpointClassName);
		if (classes.size() == 0) {
			if (this.breakpointClassName.equals("_JDIStackFrame_")) {
				// install special class
				String source =
					"public class _JDIStackFrame_ {\n" +
					"  public int foo() {\n" +
					"    return -1;\n" +
					"  }\n" +
					"}";
				test.compileAndDeploy(source, "_JDIStackFrame_");
			}
			
			// force load of class 
			test.evaluateWithExpectedDisplayString(
				("return Class.forName(\"" + this.breakpointClassName + "\");").toCharArray(),
				("class " + this.breakpointClassName).toCharArray()
			);
			classes = this.jdiVM.classesByName(this.breakpointClassName);
			if (classes.size() == 0) {
				// workaround bug in Standard VM
				Iterator iterator = this.jdiVM.allClasses().iterator();
				while (iterator.hasNext()) {
					ReferenceType type = (ReferenceType)iterator.next();
					if (type.name().equals(this.breakpointClassName)) {
						classes = new ArrayList(1);
						classes.add(type);
						break;
					}
				}
				if (classes.size() == 0) {
					throw new Error("JDI could not retrieve class for " + this.breakpointClassName);
				}
			}
		}
		ClassType clazz = (ClassType)classes.get(0);
		Method method = (Method)clazz.methodsByName(this.breakpointMethodName).get(0);
		Location location;
		if (this.breakpointLine < 0 || this.breakpointLine == Integer.MAX_VALUE) {
			location = method.location();
		} else {
			location = (Location)method.locationsOfLine(this.breakpointLine).get(0);
		}
		BreakpointRequest request = this.jdiVM.eventRequestManager().createBreakpointRequest(location);
		request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
		request.enable();

		// create a new thread that hit the breakpoint
		EvaluationTest.Requestor requestor = test.new Requestor();
		try {
			test.resetEnv();
			test.context.evaluate(
				("(new Thread() {\n" +
				"  public void run() {\n" +
				     userCode + "\n" +
				(this.breakpointClassName.equals("_JDIStackFrame_") ? "    new _JDIStackFrame_().foo();\n" : "") +
				"  }\n" +
				"  public String toString() {\n" +
				"    return \"my thread\";\n" +
				"  }\n" +
				"}).start();\n").toCharArray(),
				test.getEnv(), 
				test.getOptions(), 
				requestor, 
				test.getProblemFactory());
		} catch (InstallException e) {
			EvaluationTest.assertTrue("Target exception " + e.getMessage(), false);
		}
		EvaluationResult[] results = requestor.results;
		for (int i = 0; i < requestor.resultIndex + 1; i++){
			if (results[i].hasErrors()) {
				EvaluationTest.assertTrue("Compilation error in user code", false);
			}
		}

		// Wait for the breakpoint event
		Event event = null;
		do {
			EventSet set = this.jdiVM.eventQueue().remove();
			Iterator iterator = set.eventIterator();
			while (iterator.hasNext()) {
				event = (Event)iterator.next();
				if (event instanceof BreakpointEvent)
					break;
			}
		} while (!(event instanceof BreakpointEvent));

		// Return the suspended thread
		return ((BreakpointEvent)event).thread();
	} catch (AbsentInformationException e) {
		e.printStackTrace();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	return null;
}
protected StackFrame getStackFrame() {
	try {
		if (this.breakpointLine == Integer.MAX_VALUE) {
			return this.jdiThread.frame(1);
		} else {
			return this.jdiThread.frame(0);
		}
	} catch (IncompatibleThreadStateException e) {
		e.printStackTrace();
		return null;
	}
}
public boolean isConstructorCall() {
	if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet
		StackFrame frame = getStackFrame();
		return frame.location().method().isConstructor();
	}
	return false;
}
public boolean isStatic() {
	if (this.breakpointLine != Integer.MAX_VALUE) { // if not in a code snippet
		StackFrame frame = getStackFrame();
		return frame.location().method().isStatic();
	}
	return false;
}
public int[] localVariableModifiers() {
	try {
		StackFrame frame = getStackFrame();
		List variables = frame.visibleVariables();
		int[] modifiers = new int[variables.size()];
/*		Iterator iterator = variables.iterator();
		int i = 0;
		while (iterator.hasNext()) {
			LocalVariable var = (LocalVariable)iterator.next();
			// TBD modifiers[i++] = var. ??? ;
		}
*/		return modifiers;
	} catch (AbsentInformationException e) {
		return null;
	}
}
public char[][] localVariableNames() {
	try {
		StackFrame frame = getStackFrame();
		Iterator variables = frame.visibleVariables().iterator();
		Vector names = new Vector();
		while (variables.hasNext()) {
			LocalVariable var = (LocalVariable)variables.next();
			names.addElement(var.name().toCharArray());
		}
		char[][] result = new char[names.size()][];
		names.copyInto(result);
		return result;
	} catch (AbsentInformationException e) {
		return null;
	}
}
public char[][] localVariableTypeNames() {
	try {
		StackFrame frame = getStackFrame();
		Iterator variables = frame.visibleVariables().iterator();
		Vector names = new Vector();
		while (variables.hasNext()) {
			LocalVariable var = (LocalVariable)variables.next();
			names.addElement(var.typeName().toCharArray());
		}
		char[][] result = new char[names.size()][];
		names.copyInto(result);
		return result;
	} catch (AbsentInformationException e) {
		return null;
	}
}
public boolean run(String codeSnippetClassName) {
		ClassType codeSnippetClass;
		ObjectReference codeSnippet;
		Method method;
		List arguments;
		ObjectReference codeSnippetRunner;
		try {
			// Get the code snippet class
			List classes = jdiVM.classesByName(codeSnippetClassName);
			while (classes.size() == 0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
				classes = jdiVM.classesByName(codeSnippetClassName);
				if (classes.size() == 0) {
					// workaround bug in Standard VM
					Iterator iterator = this.jdiVM.allClasses().iterator();
					while (iterator.hasNext()) {
						ReferenceType type = (ReferenceType)iterator.next();
						if (type.name().equals(codeSnippetClassName)) {
							classes = new ArrayList(1);
							classes.add(type);
							break;
						}
					}
				}
			}
			codeSnippetClass = (ClassType)classes.get(0);

			// Create a new code snippet
			Method constructor = (Method)codeSnippetClass.methodsByName("<init>").get(0);
			codeSnippet = codeSnippetClass.newInstance(jdiThread, constructor, new ArrayList(), ClassType.INVOKE_SINGLE_THREADED);

			// Install local variables and "this" into generated fields
			StackFrame stackFrame = getStackFrame();
			try {
				Iterator variables = stackFrame.visibleVariables().iterator();
				while (variables.hasNext()) {
					LocalVariable jdiVariable = (LocalVariable)variables.next();
					Value value = stackFrame.getValue(jdiVariable);
					Field field = codeSnippetClass.fieldByName(new String(LOCAL_VAR_PREFIX) + jdiVariable.name());
					codeSnippet.setValue(field, value);
				}
			} catch (AbsentInformationException e) {
				// No variables
			}
			Field delegateThis = codeSnippetClass.fieldByName(new String(DELEGATE_THIS));
			ObjectReference thisObject;
			if (delegateThis != null && ((thisObject = stackFrame.thisObject()) != null)) {
				codeSnippet.setValue(delegateThis, thisObject);
			}

			// Get the code snippet runner
			ClassType codeSnippetRunnerClass = (ClassType)jdiVM.classesByName(CODE_SNIPPET_RUNNER_CLASS_NAME).get(0);
			Field theRunner = codeSnippetRunnerClass.fieldByName(THE_RUNNER_FIELD);
			codeSnippetRunner = (ObjectReference)codeSnippetRunnerClass.getValue(theRunner);

			// Get the method 'runCodeSnippet' and its arguments		
			method = (Method)codeSnippetRunnerClass.methodsByName(RUN_CODE_SNIPPET_METHOD).get(0);
			arguments = new ArrayList();
			arguments.add(codeSnippet);
		} catch (ClassNotLoadedException e) {
			e.printStackTrace();
			return false;
		} catch (IncompatibleThreadStateException e) {
			e.printStackTrace();
			return false;
		} catch (InvalidTypeException e) {
			e.printStackTrace();
			return false;
		} catch (InvocationException e) {
			e.printStackTrace();
			return false;
		}

		try {
			// Invoke runCodeSnippet(CodeSnippet)
			codeSnippetRunner.invokeMethod(jdiThread, method, arguments, ClassType.INVOKE_SINGLE_THREADED);

			// Retrieve values of local variables and put them back in the stack frame
			StackFrame stackFrame = getStackFrame();
			try {
				Iterator variables = stackFrame.visibleVariables().iterator();
				while (variables.hasNext()) {
					LocalVariable jdiVariable = (LocalVariable)variables.next();
					Field field = codeSnippetClass.fieldByName(new String(LOCAL_VAR_PREFIX) + jdiVariable.name());
					Value value = codeSnippet.getValue(field);
					stackFrame.setValue(jdiVariable, value);
				}
			} catch (AbsentInformationException e) {
				// No variables
			}
		} catch (ClassNotLoadedException e) {
			e.printStackTrace();
		} catch (IncompatibleThreadStateException e) {
			e.printStackTrace();
		} catch (InvalidTypeException e) {
			e.printStackTrace();
		} catch (InvocationException e) {
			e.printStackTrace();
		}
		return true;
	}
}
