package org.eclipse.debug.jdi.tests;

/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
This file is 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
**********************************************************************/

import java.util.List;

import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.InvocationException;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadGroupReference;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.event.ThreadStartEvent;

/**
 * Tests for JDI com.sun.jdi.ThreadReference
 * and JDWP Thread command set.
 */
public class ThreadReferenceTest extends AbstractJDITest {

	private ThreadReference fThread;
	/**
	 * Creates a new test .
	 */
	public ThreadReferenceTest() {
		super();
	}
	/**
	 * Init the fields that are used by this test only.
	 */
	public void localSetUp() {
		// Get thread
		fThread = getThread();
	}
	/**
	 * Run all tests and output to standard output.
	 */
	public static void main(java.lang.String[] args) {
		new ThreadReferenceTest().runSuite(args);
	}
	/**
	 * Gets the name of the test case.
	 */
	public String getName() {
		return "com.sun.jdi.ThreadReference";
	}
	/**
	 * Test JDI currentContendedMonitor().
	 */
	public void testJDICurrentContendedMonitor() {
		if (fVM.canGetCurrentContendedMonitor()) {
			try {
				assertTrue("1", fThread.currentContendedMonitor() == null);
			} catch (IncompatibleThreadStateException e) {
				assertTrue("2", false);
			}
		}
	}
	/**
	 * Test JDI frame(int).
	 */
	public void testJDIFrame() {
		try {
			StackFrame frame = fThread.frame(0);
			assertTrue("1", fThread.frames().contains(frame));
		} catch (IncompatibleThreadStateException e) {
			assertTrue("2", false);
		}
	}
	/**
	 * Test JDI frameCount.
	 */
	public void testJDIFrameCount() {
		try {
			int count = fThread.frameCount();
			assertTrue("1", count <= 4);
		} catch (IncompatibleThreadStateException e) {
			assertTrue("2", false);
		}
	}
	/**
	 * Test JDI frames() and JDWP 'Thread - Get frames'.
	 */
	public void testJDIFrames() {
		List frames = null;
		try {
			frames = fThread.frames();
		} catch (IncompatibleThreadStateException e) {
			assertTrue("1", false);
		}
		assertTrue("2", frames.size() > 0);
	}
	/**
	 * Test JDI interrupt()().
	 */
	public void testJDIInterrupt() {
		assertEquals("1", 1, fThread.suspendCount());
		fThread.interrupt();
		assertEquals("2", 1, fThread.suspendCount());
	}
	/**
	 * Test JDI isAtBreakpoint().
	 */
	public void testJDIIsAtBreakpoint() {
		assertTrue("1", !fThread.isAtBreakpoint());
	}
	/**
	 * Test JDI isSuspended().
	 */
	public void testJDIIsSuspended() {
		assertTrue("1", fThread.isSuspended());
	}
	/**
	 * Test JDI name() and JDWP 'Thread - Get name'.
	 */
	public void testJDIName() {
		assertEquals("1", "Test Thread", fThread.name());
	}
	/**
	 * Test JDI ownedMonitors().
	 */
	public void testJDIOwnedMonitors() {
		if (fVM.canGetOwnedMonitorInfo()) {
			waitUntilReady();
			try {
				assertEquals("1", 1, fThread.ownedMonitors().size());
			} catch (IncompatibleThreadStateException e) {
				assertTrue("2", false);
			}
		}
	}
	/**
	 * Test JDI status() and JDWP 'Thread - Get status'.
	 */
	public void testJDIStatus() {
		int status = fThread.status();
		assertTrue(
			"1",
			((status == ThreadReference.THREAD_STATUS_RUNNING)
				|| (status == ThreadReference.THREAD_STATUS_SLEEPING)
				|| (status == ThreadReference.THREAD_STATUS_WAIT)));
	}
	/**
	 * Test JDI stop(ObjectReference).
	 */
	public void testJDIStop() {
		// Make sure the entire VM is not suspended before we start a new thread
		// (otherwise this new thread will start suspended and we will never get the
		// ThreadStart event)
		fVM.resume();

		// Trigger a thread start event to get a new thread
		ThreadStartEvent event =
			(ThreadStartEvent) triggerAndWait(fVM
				.eventRequestManager()
				.createThreadStartRequest(),
				"ThreadStartEvent",
				false);
		ThreadReference thread = event.thread();

		// Create a java.lang.ThreadDeath instance in 
		java.util.List classes = fVM.classesByName("java.lang.ThreadDeath");
		assertTrue("1", classes.size() != 0);
		ClassType threadDeathClass = (ClassType) classes.get(0);
		Method constructor =
			threadDeathClass.concreteMethodByName("<init>", "()V");
		ObjectReference threadDeath = null;
		try {
			threadDeath =
				threadDeathClass.newInstance(
					thread,
					constructor,
					new java.util.LinkedList(),
					ClassType.INVOKE_SINGLE_THREADED);
			threadDeath.disableCollection();
			// This object is going to be used for the lifetime of the VM.
		} catch (ClassNotLoadedException e) {
			assertTrue("2", false);
		} catch (InvalidTypeException e) {
			assertTrue("3", false);
		} catch (InvocationException e) {
			assertTrue("4", false);
		} catch (IncompatibleThreadStateException e) {
			assertTrue("5", false);
		}

		// Stop the thread
		try {
			thread.stop(threadDeath);
		} catch (InvalidTypeException e) {
			assertTrue("6", false);
		}

		waitUntilReady();

	}
	/**
	 * Test JDI suspend() and resume() 
	 * and JDWP 'Thread - Suspend' and 'Thread - Resume'.
	 */
	public void testJDISuspendResume() {
		assertEquals("1", 1, fThread.suspendCount());
		fThread.resume();
		assertTrue("2", !fThread.isSuspended());
		fThread.suspend();
		assertTrue("3", fThread.isSuspended());

		waitUntilReady();
	}
	/**
	 * Test JDI threadGroup() and JDWP 'Thread - Get threadGroup'.
	 */
	public void testJDIThreadGroup() {
		assertTrue("1", fThread.threadGroup() instanceof ThreadGroupReference);
	}
}
