/*******************************************************************************
 * Copyright (c) 2007 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.debug.test.stepping;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ILineBreakpoint;
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.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;

import com.sun.jdi.InvalidTypeException;

/**
 * Tests forcing return from method.
 *
 * @since 3.3
 */
public class ForceReturnTests extends AbstractDebugTest {

	/**
	 * Creates test case.
	 *
	 * @param name test name
	 */
	public ForceReturnTests(String name) {
		super(name);
	}

	/**
	 * Tests forcing the return of an integer from top stack frame
	 *
	 * @throws Exception
	 */
	public void testForceIntReturnTopFrame() throws Exception {
		String typeName = "ForceReturnTests";
		ILineBreakpoint bp2 = createLineBreakpoint(22, typeName);
		ILineBreakpoint bp = createLineBreakpoint(31, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				stackFrame.forceReturn(target.newValue(42));
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 22) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("x");
				assertNotNull("Missing variable 'x'", var);
				assertEquals("Return value incorrect", target.newValue(42), var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests forcing the return of an integer from non-top stack frame
	 *
	 * @throws Exception
	 */
	public void testForceIntReturn() throws Exception {
		String typeName = "ForceReturnTestsTwo";
		ILineBreakpoint bp2 = createLineBreakpoint(23, typeName);
		ILineBreakpoint bp = createLineBreakpoint(37, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				IJavaValue retValue = target.newValue(1);
				stackFrame = (IJavaStackFrame) thread.getStackFrames()[1];
				stackFrame.forceReturn(retValue);
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 23) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("x");
				assertNotNull("Missing variable 'x'", var);
				assertEquals("Return value incorrect", retValue, var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests forcing the return of a string from top frame
	 *
	 * @throws Exception
	 */
	public void testForceStringReturnTopFrame() throws Exception {
		String typeName = "ForceReturnTests";
		ILineBreakpoint bp2 = createLineBreakpoint(24, typeName);
		ILineBreakpoint bp = createLineBreakpoint(36, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				IJavaValue stringValue = target.newValue("forty two");
				stackFrame.forceReturn(stringValue);
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 24) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("s");
				assertNotNull("Missing variable 's'", var);
				assertEquals("Return value incorrect", stringValue, var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests forcing the return of a string from a non top frame
	 *
	 * @throws Exception
	 */
	public void testForceStringReturn() throws Exception {
		String typeName = "ForceReturnTestsTwo";
		ILineBreakpoint bp2 = createLineBreakpoint(25, typeName);
		ILineBreakpoint bp = createLineBreakpoint(46, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				IJavaValue stringValue = target.newValue("forty two");
				stackFrame = (IJavaStackFrame) thread.getStackFrames()[1];
				stackFrame.forceReturn(stringValue);
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 25) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("s");
				assertNotNull("Missing variable 's'", var);
				assertEquals("Return value incorrect", stringValue, var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests forcing the return of an object from top frame.
	 *
	 * @throws Exception
	 */
	public void testForceObjectReturnTopFrame() throws Exception {
		String typeName = "ForceReturnTests";
		ILineBreakpoint bp2 = createLineBreakpoint(26, typeName);
		ILineBreakpoint bp = createLineBreakpoint(43, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				IJavaValue objectValue = target.newValue("a string");
				stackFrame.forceReturn(objectValue);
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 26) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("v");
				assertNotNull("Missing variable 'v'", var);
				assertEquals("Return value incorrect", objectValue, var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests forcing the return of an object from non-top frame.
	 *
	 * @throws Exception
	 */
	public void testForceObjectReturn() throws Exception {
		String typeName = "ForceReturnTestsTwo";
		ILineBreakpoint bp2 = createLineBreakpoint(27, typeName);
		ILineBreakpoint bp = createLineBreakpoint(56, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
				IJavaValue objectValue = target.newValue("a string");
				stackFrame = (IJavaStackFrame) thread.getStackFrames()[1];
				stackFrame.forceReturn(objectValue);
				Object source = waiter.waitForEvent();
				assertTrue("Suspend should be from thread", source instanceof IJavaThread);
				thread = (IJavaThread) source;
				stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				if (stackFrame.getLineNumber() < 27) {
					// @see bug 197282. Some VMs optimize the variable assignment and may
					// already have performed the assignment
					thread = resumeToLineBreakpoint(thread, bp2);
					stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
				}
				IJavaVariable var = stackFrame.findVariable("v");
				assertNotNull("Missing variable 'v'", var);
				assertEquals("Return value incorrect", objectValue, var.getValue());
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests that an incompatible type causes an exception in top frame
	 *
	 * @throws Exception
	 */
	public void testIncompatibleReturnTypeTopFrame() throws Exception {
		String typeName = "ForceReturnTests";
		ILineBreakpoint bp = createLineBreakpoint(43, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				IJavaValue objectValue = target.newValue(42);
				try {
					stackFrame.forceReturn(objectValue);
				} catch (DebugException e) {
					assertTrue("Should be invalid type exception", e.getStatus().getException() instanceof InvalidTypeException);
					return;
				}
				assertTrue("Should have caused incompatible return type exception", false);
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}

	/**
	 * Tests that an incompatible type causes an exception in non top frame
	 *
	 * @throws Exception
	 */
	public void testIncompatibleReturnType() throws Exception {
		String typeName = "ForceReturnTestsTwo";
		ILineBreakpoint bp = createLineBreakpoint(46, typeName);

		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp, false);
			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
			IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget();
			if (target.supportsForceReturn()) {
				assertTrue("Force return should be enabled", stackFrame.canForceReturn());
				IJavaValue objectValue = target.newValue(42);
				stackFrame = (IJavaStackFrame) thread.getStackFrames()[1];
				try {
					stackFrame.forceReturn(objectValue);
				} catch (DebugException e) {
					assertTrue("Should be invalid type exception", e.getStatus().getException() instanceof InvalidTypeException);
					return;
				}
				assertTrue("Should have caused incompatible return type exception", false);
			}
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}
	}
}
