/*******************************************************************************
 * Copyright (c) 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.debug.tests.state;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdi.internal.jdwp.JdwpPacket;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;

/**
 * Tests that state refresh works after modifying the target state
 * with a custom JDWP command.
 * 
 * @since 3.6
 */
public class RefreshStateTests extends AbstractDebugTest {

	public RefreshStateTests(String name) {
		super(name);
	}
	
	/**
	 * Resume a thread behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testThreadHasResumed() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		ILineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// Resume thread (set 11, command 3)
			IJavaObject reference = thread.getThreadObject();
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			outData.writeLong(reference.getUniqueId());
			byte[] reply = jdiTarget.sendCommand((byte)11, (byte)3, outBytes.toByteArray());
			JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
			
			assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			
			// model should still be suspended
			assertTrue("Model should be in suspended state", thread.isSuspended());
			
			// refresh the model, expect a resume event
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, thread);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Thread never sent resume event", source);
			assertEquals("Wrong thread resumed", thread, source);
			// model should now be in running state
			assertFalse("Model should now be running", thread.isSuspended());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}
	
	/**
	 * Resume all threads behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testAllThreadsResumed() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		IJavaLineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_VM);
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// Resume each thread (set 11, command 3)
			IThread[] threads = jdiTarget.getThreads();
			for (int i = 0; i < threads.length; i++) {
				IJavaThread jThread = (IJavaThread) threads[i];
				IJavaObject reference = jThread.getThreadObject();
				ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
				DataOutputStream outData = new DataOutputStream(outBytes);
				outData.writeLong(reference.getUniqueId());
				byte[] reply = jdiTarget.sendCommand((byte)11, (byte)3, outBytes.toByteArray());
				JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
				assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			}
			
			// model should still be suspended
			assertTrue("Model should be in suspended state", jdiTarget.isSuspended());
			
			// refresh the model, expect a resume event
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, jdiTarget);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Thread never sent resume event", source);
			// model should now be in running state
			assertFalse("Model should now be running", jdiTarget.isSuspended());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}
	
	/**
	 * Suspend a thread behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testThreadHasSuspended() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		ILineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// resume the thread to get into running state
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, thread);
			thread.resume();
			waiter.waitForEvent();
			// model should now be in running state
			assertFalse("Model should now be running", thread.isSuspended());
			
			// suspend the thread with a JDWP command (set 11, command 2)
			IJavaObject reference = thread.getThreadObject();
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			outData.writeLong(reference.getUniqueId());
			byte[] reply = jdiTarget.sendCommand((byte)11, (byte)2, outBytes.toByteArray());
			JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
			
			assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			
			// model should still be running
			assertFalse("Model should be in running state", thread.isSuspended());
			
			// refresh the model, expect a suspend event
			waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Thread never sent suspend event", source);
			assertEquals("Wrong thread suspended", thread, source);
			
			// model should be suspended now
			assertTrue("Model should be in suspended state", thread.isSuspended());
			
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}	
	
	/**
	 * Suspend all threads behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testAllThreadsSuspended() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		ILineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// resume the thread to get into running state
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, thread);
			thread.resume();
			waiter.waitForEvent();
			// model should now be in running state
			assertFalse("Model should now be running", thread.isSuspended());
			
			IThread[] threads = jdiTarget.getThreads();
			for (int i = 0; i < threads.length; i++) {
				IJavaThread jThread = (IJavaThread) threads[i];
				// suspend each thread with a JDWP command (set 11, command 2)
				IJavaObject reference = jThread.getThreadObject();
				ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
				DataOutputStream outData = new DataOutputStream(outBytes);
				outData.writeLong(reference.getUniqueId());
				byte[] reply = jdiTarget.sendCommand((byte)11, (byte)2, outBytes.toByteArray());
				JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
				assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			}
			
			
			// model should still be running
			assertFalse("Model should be in running state", jdiTarget.isSuspended());
			
			// refresh the model, expect a suspend event
			waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, jdiTarget);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Target never sent suspend event", source);
			
			// model should be suspended now
			assertTrue("Model should be in suspended state", jdiTarget.isSuspended());
			
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}		

	/**
	 * Suspend the entire target behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testTargetHasSuspended() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		ILineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// resume the thread to get into running state
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, thread);
			thread.resume();
			waiter.waitForEvent();
			// model should now be in running state
			assertFalse("Model should now be running", thread.isSuspended());
			
			// suspend the target with a JDWP command (set 1, command 8)
			IJavaObject reference = thread.getThreadObject();
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			outData.writeLong(reference.getUniqueId());
			byte[] reply = jdiTarget.sendCommand((byte)1, (byte)8, outBytes.toByteArray());
			JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
			
			assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			
			// model should still be running
			assertFalse("Model should be in running state", jdiTarget.isSuspended());
			
			// refresh the model, expect a suspend event
			waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, jdiTarget);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Target never sent suspend event", source);
			
			// model should be suspended now
			assertTrue("Model should be in suspended state", jdiTarget.isSuspended());
			
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}		
	
	/**
	 * Resume a target behind the scenes and ensure model state updates appropriately.
	 * 
	 * @throws CoreException
	 */
	public void testTargetHasResumed() throws Exception {
		String typeName = "org.eclipse.debug.tests.targets.CallLoop";
		IJavaLineBreakpoint bp = createLineBreakpoint(16, "org.eclipse.debug.tests.targets.Looper");
		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_VM);
		
		IJavaThread thread = null;
		try {
			thread= launchToLineBreakpoint(typeName, bp);
			IJavaDebugTarget jdiTarget = (IJavaDebugTarget) thread.getDebugTarget();
			// Resume target (set 1, command 9)
			IJavaObject reference = thread.getThreadObject();
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			outData.writeLong(reference.getUniqueId());
			byte[] reply = jdiTarget.sendCommand((byte)1, (byte)9, outBytes.toByteArray());
			JdwpReplyPacket packet = (JdwpReplyPacket) JdwpPacket.build(reply);
			
			assertEquals("Unexpected error code in reply packet", 0, packet.errorCode());
			
			// model should still be suspended
			assertTrue("Model should be in suspended state", jdiTarget.isSuspended());
			
			// refresh the model, expect a resume event
			DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.RESUME, jdiTarget);
			jdiTarget.refreshState();
			Object source = waiter.waitForEvent();
			assertNotNull("Target never sent resume event", source);
			// model should now be in running state
			assertFalse("Model should now be running", jdiTarget.isSuspended());
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
		}	
	}	
}
