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

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.testplugin.DebugElementKindEventDetailWaiter;
import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMConnector;
import org.eclipse.jdt.launching.JavaRuntime;

import com.sun.jdi.connect.Connector;

/**
 * Tests attaching to a remote java application
 */
public class RemoteJavaApplicationTests extends AbstractDebugTest {
	
	public RemoteJavaApplicationTests(String name) {
		super(name);
	}

	/**
	 * Tests a Standard (Socket Attach) VM connection.
	 * @throws Exception
	 */
	public void testAttach() throws Exception {
		String typeName = "Breakpoints";
		createLineBreakpoint(52, typeName);
		
		// create launch config to launch VM in debug mode waiting for attach
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		ILaunchConfigurationWorkingCopy config = type.newInstance(null, "Launch Remote VM");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "Breakpoints");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "-Djava.compiler=NONE -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,suspend=y,server=y");
		// use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2)
		Map map = new HashMap(1);
		map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);		
		ILaunchConfiguration launchRemoteVMConfig = config.doSave();
		
		// create a launch config to do the attach
		type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION);
		config = type.newInstance(null, "Remote Breakpoints");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, true);
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR);
		IVMConnector connector = JavaRuntime.getVMConnector(IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR);
		Map def = connector.getDefaultArguments();
		Map argMap = new HashMap(def.size());
		Iterator iter = connector.getArgumentOrder().iterator();
		while (iter.hasNext()) {
			String key = (String)iter.next();
			Connector.Argument arg = (Connector.Argument)def.get(key);
			argMap.put(key, arg.toString()); 
		}
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, argMap);		
		ILaunchConfiguration attachConfig = config.doSave();		
			
		// launch remote VM
		ILaunch launch = launchRemoteVMConfig.launch(ILaunchManager.RUN_MODE, null);
		
		// attach	
		IJavaThread thread= null;
		try {
			CoreException exception = null;
			int attempts = 0;
			boolean connected = false;
			while ((attempts < 2) && !connected) {
				try {
					attempts++;
					exception = null;
					thread= launchToBreakpoint(attachConfig);
					connected = true;
				} catch (CoreException e) {
					// try again, in case the VM is not yet ready
					exception = e;
					Thread.sleep(2000);
				}
			}
			if (exception != null) {
				throw exception;
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			IBreakpoint hit = getBreakpoint(thread);
			assertNotNull("suspended, but not by breakpoint", hit);
			assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
			ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
			int lineNumber = breakpoint.getLineNumber();
			int stackLine = thread.getTopStackFrame().getLineNumber();
			assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine);
			breakpoint.delete();
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
		}		
	}
	
	/**
	 * Tests a Standard (Socket Listen) VM connection.
	 * @throws Exception
	 */
	public void testListen() throws Exception {
		String typeName = "Breakpoints";
		createLineBreakpoint(52, typeName);
		
		// create a launch config to listen for the vm
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION);
		ILaunchConfigurationWorkingCopy config = type.newInstance(null, "Remote Breakpoints");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, true);
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, IJavaLaunchConfigurationConstants.ID_SOCKET_LISTEN_VM_CONNECTOR);
		IVMConnector connector = JavaRuntime.getVMConnector(IJavaLaunchConfigurationConstants.ID_SOCKET_LISTEN_VM_CONNECTOR);
		Map def = connector.getDefaultArguments();
		Map argMap = new HashMap(def.size());
		Iterator iter = connector.getArgumentOrder().iterator();
		while (iter.hasNext()) {
			String key = (String)iter.next();
			Connector.Argument arg = (Connector.Argument)def.get(key);
			argMap.put(key, arg.toString()); 
		}
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, argMap);		
		ILaunchConfiguration listenConfig = config.doSave();		

		// create launch config to launch VM that will connect to the waiting listener
		type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
		config = type.newInstance(null, "Launch Remote VM");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "Breakpoints");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "-Djava.compiler=NONE -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,suspend=y,server=n");
		// use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2)
		Map map = new HashMap(1);
		map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java");
		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);		
		ILaunchConfiguration launchRemoteVMConfig = config.doSave();
				
		ILaunch listenerLaunch = null;
		IJavaThread thread = null;
		
		
		try {
			
			DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.MODEL_SPECIFIC, IProcess.class, IJavaLaunchConfigurationConstants.DETAIL_CONFIG_READY_TO_ACCEPT_REMOTE_VM_CONNECTION);
			waiter.setTimeout(DEFAULT_TIMEOUT);
			
			IProcess process = null;
			CoreException exception = null;
			int attempts = 0;
			boolean connected = false;
			while ((attempts < 2) && !connected) {
				try {
					attempts++;
					exception = null;
					process = (IProcess)launchAndWait(listenConfig,waiter);
					connected = true;
				} catch (CoreException e) {
					// try again, in case the VM is not yet ready
					exception = e;
					Thread.sleep(2000);
				}
			}
			if (exception != null) {
				throw exception;
			}
			
			assertNotNull("Launch of the not successful", process);
			listenerLaunch = process.getLaunch();
			
			
			waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT);
			waiter.setTimeout(DEFAULT_TIMEOUT);
			
			exception = null;
			attempts = 0;
			connected = false;
			while ((attempts < 2) && !connected) {
				try {
					attempts++;
					exception = null;
					thread = (IJavaThread)launchAndWait(launchRemoteVMConfig,ILaunchManager.RUN_MODE,waiter,true);
					connected = true;
				} catch (CoreException e) {
					// try again, in case the VM is not yet ready
					exception = e;
					Thread.sleep(2000);
				}
			}
			if (exception != null) {
				throw exception;
			}
			assertNotNull("Breakpoint not hit within timeout period", thread);
			IBreakpoint hit = getBreakpoint(thread);
			assertNotNull("suspended, but not by breakpoint", hit);
			assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
			ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
			int lineNumber = breakpoint.getLineNumber();
			int stackLine = thread.getTopStackFrame().getLineNumber();
			assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine);
			breakpoint.delete();
			
			
		} finally {
			terminateAndRemove(thread);
			removeAllBreakpoints();
			if (listenerLaunch != null){
				DebugPlugin.getDefault().getLaunchManager().removeLaunch(listenerLaunch);
			}
		}
	}

}
