/*******************************************************************************
 *  Copyright (c) 2000, 2012 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<String, String> map = new HashMap<String, String>(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<String, ? extends Connector.Argument> def = connector.getDefaultArguments();
		Map<String, String> argMap = new HashMap<String, String>(def.size());
		Iterator<String> iter = connector.getArgumentOrder().iterator();
		while (iter.hasNext()) {
			String key = iter.next();
			Connector.Argument arg = 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<String, ? extends Connector.Argument> def = connector.getDefaultArguments();
		Map<String, String> argMap = new HashMap<String, String>(def.size());
		Iterator<String> iter = connector.getArgumentOrder().iterator();
		while (iter.hasNext()) {
			String key = iter.next();
			Connector.Argument arg = 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<String, String> map = new HashMap<String, String>(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);
			}
		}
	}

}
