/*******************************************************************************
 * Copyright (c) 2000, 2009 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.core.tests.eval;

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

import junit.framework.Assert;

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;
	long timeout;
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, test, userCode, breakpointClassName, breakpointMethodName, breakpointLine, 10000/*timeout*/);
	
}
public JDIStackFrame(
	VirtualMachine jdiVM,
	DebugEvaluationTest test,
	String userCode,
	String breakpointClassName,
	String breakpointMethodName,
	int breakpointLine,
	long timeout) {
	
	this.jdiVM = jdiVM;
	this.userCode = userCode;
	this.breakpointClassName = breakpointClassName;
	this.breakpointMethodName = breakpointMethodName;
	this.breakpointLine = breakpointLine;
	this.timeout = timeout;

	test.jdiStackFrame = null;
	this.jdiThread = 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" +
				     this.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.getCompilerOptions(),
				requestor,
				test.getProblemFactory());
		} catch (InstallException e) {
			Assert.assertTrue("Target exception " + e.getMessage(), false);
		}
		EvaluationResult[] results = requestor.results;
		for (int i = 0; i < requestor.resultIndex + 1; i++){
			if (results[i].hasErrors()) {
				Assert.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);
		}
		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
			long start = System.currentTimeMillis();
			List classes = this.jdiVM.classesByName(codeSnippetClassName);
			while (classes.size() == 0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
				classes = this.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;
						}
					}
					if (classes.size() == 0 && (System.currentTimeMillis()-start) > this.timeout) {
						return false;
					}
				}
			}
			codeSnippetClass = (ClassType)classes.get(0);

			// Create a new code snippet
			Method constructor = (Method)codeSnippetClass.methodsByName("<init>").get(0);
			codeSnippet = codeSnippetClass.newInstance(this.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)this.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(this.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;
	}
}
