/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
/*
 * $RCSfile: LocalProxyLaunchDelegate.java,v $ $Revision: 1.33 $ $Date: 2006/02/21 17:16:44 $
 */
package org.eclipse.jem.internal.proxy.remote;

import java.io.File;
import java.io.IOException;
import java.net.*;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Level;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.*;
import org.eclipse.debug.core.model.*;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.launching.*;

import org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.remote.awt.REMRegisterAWT;
import org.eclipse.jem.util.TimerTests;
import org.eclipse.jem.util.logger.proxy.Logger;


/**
 * Launch Delegate for launching Local (i.e. remote vm is on local system). Here "remote" means the
 * registry is not in the IDE but in a separate VM, and "local" means that is in on the local
 * physical machine and not on a separate machine.
 * 
 * @since 1.0.0
 */
public class LocalProxyLaunchDelegate extends AbstractJavaLaunchConfigurationDelegate {

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration,
	 *      java.lang.String, org.eclipse.debug.core.ILaunch,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor pm) throws CoreException {

		String launchKey = configuration.getAttribute(IProxyConstants.ATTRIBUTE_LAUNCH_KEY, (String) null);
		if (launchKey == null)
			abort(ProxyRemoteMessages.ProxyRemoteNoLaunchKey, null, 0); 

		// In Eclipse, even if private, a launch will show up in the debug process tree and in the console viewer.
		// To be absolutely private, we need to remove the launch which has already been added.
		if (ProxyLaunchSupport.ATTR_PRIVATE != null && configuration.getAttribute(ProxyLaunchSupport.ATTR_PRIVATE, false)) 
			DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);		
		if (pm == null) {
			pm = new NullProgressMonitor();
		}

		IJavaProject project = getJavaProject(configuration);
		String name = configuration.getAttribute(IProxyConstants.ATTRIBUTE_VM_TITLE, (String) null);
		if (name == null)
			name = MessageFormat.format(ProxyRemoteMessages.ProxyRemoteVMName, new Object[] { project != null ? project.getProject().getName() : "" });  //$NON-NLS-1$
		else
			name = MessageFormat.format(ProxyRemoteMessages.ProxyRemoteVMNameWithComment, new Object[] { project != null ? project.getProject().getName() : "", name });  //$NON-NLS-1$

		String stepId = "Launch VM ( " + name + " )"; //$NON-NLS-1$ //$NON-NLS-2$
		TimerTests.basicTest.startStep(stepId);
		// Problem with launch, can't have double-quotes in vmName.
		if (name.indexOf('"') != -1)
			name = name.replace('"', '\'');

		pm.beginTask("", 500); //$NON-NLS-1$
		pm.subTask(MessageFormat.format(ProxyRemoteMessages.ProxyRemoteLaunchVM, new Object[] { name })); 
		// check for cancellation
		if (pm.isCanceled())
			return;

		IVMInstall vm = verifyVMInstall(configuration);

		IVMRunner runner = vm.getVMRunner(mode);
		if (runner == null) {
			abort(MessageFormat.format(ProxyRemoteMessages.Proxy_NoRunner_ERROR_, new Object[] { name }), null, 0); 
		}

		File workingDir = verifyWorkingDirectory(configuration);
		String workingDirName = null;
		if (workingDir != null) {
			workingDirName = workingDir.getAbsolutePath();
		}

		// Environment variables
		String[] envp = DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);

		// Program & VM args
		String pgmArgs = getProgramArguments(configuration);
		String vmArgs = getVMArguments(configuration);
		ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);

		// VM-specific attributes
		Map vmAttributesMap = getVMSpecificAttributesMap(configuration);

		pm.worked(100);
		
		// Now let's get the classpaths created through the contributors.
		URL[] classpath = ProxyLaunchSupport.convertStringPathsToURL(getClasspath(configuration));
		String[][] bootpathInfoStrings = getBootpathExt(vmAttributesMap);
		URL[][] bootpathInfo = new URL[][]{
				ProxyLaunchSupport.convertStringPathsToURL(bootpathInfoStrings[0]),
				ProxyLaunchSupport.convertStringPathsToURL(bootpathInfoStrings[1]),
				ProxyLaunchSupport.convertStringPathsToURL(bootpathInfoStrings[2]),
		};
		ProxyLaunchSupport.LaunchInfo launchInfo = ProxyLaunchSupport.getInfo(launchKey);
		final IConfigurationContributor[] contributors = launchInfo.contributors;
		final LocalFileConfigurationContributorController controller =
			new LocalFileConfigurationContributorController(classpath, bootpathInfo, launchInfo);
		if (contributors != null) {		
			for (int i = 0; i < contributors.length; i++) {
				// Run in safe mode so that anything happens we don't go away.
				final int ii = i;
				SafeRunner.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// Don't need to do anything. Platform.run logs it for me.
					}

					public void run() throws Exception {
						contributors[ii].contributeClasspaths(controller);
					}
				});
			}
		}

		// Add in the required ones by the Proxy support. These are hard-coded since they are
		// required.
		ProxyRemoteUtil.updateClassPaths(controller);
		addInFragmentLibraries(controller, launchInfo.getConfigInfo());

		classpath = controller.getFinalClasspath();
		if (bootpathInfo[0] != controller.getFinalPrependBootpath()) {
		    if (vmAttributesMap == null)
		        vmAttributesMap = new HashMap(2);
		    vmAttributesMap.put(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_PREPEND, ProxyLaunchSupport.convertURLsToStrings(bootpathInfo[0]));
		}
		if (bootpathInfo[2] != controller.getFinalAppendBootpath()) {
		    if (vmAttributesMap == null)
		        vmAttributesMap = new HashMap(2);
		    vmAttributesMap.put(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_APPEND, ProxyLaunchSupport.convertURLsToStrings(bootpathInfo[2]));
		}

		// check for cancellation
		if (pm.isCanceled())
			return;
		pm.worked(100);

		// Create VM config
		VMRunnerConfiguration runConfig =
			new VMRunnerConfiguration("org.eclipse.jem.internal.proxy.vm.remote.RemoteVMApplication", ProxyLaunchSupport.convertURLsToStrings(classpath)); //$NON-NLS-1$

		REMProxyFactoryRegistry registry = new REMProxyFactoryRegistry(ProxyRemoteUtil.getRegistryController(), name);
		Integer registryKey = registry.getRegistryKey();

		Integer bufSize = Integer.getInteger("proxyvm.bufsize"); //$NON-NLS-1$
		if (bufSize == null)
			bufSize = new Integer(16000);

		int masterServerPort = ProxyRemoteUtil.getRegistryController().getMasterSocketPort();

		// See if debug mode is requested.
		DebugModeHelper dh = new DebugModeHelper();
		boolean debugMode = dh.debugMode(name);
		boolean useNoverify = ProxyPlugin.getPlugin().getPluginPreferences().getBoolean(ProxyPlugin.PREFERENCES_VM_NOVERIFY_KEY);

		String[] evmArgs = execArgs.getVMArgumentsArray();
		
		int extraArgs = 4;	// Number of extra standard args added (if number changes below, this must change)
		if (debugMode)
			extraArgs+=4;	// Number of extra args added for debug mode (if number changes below, this must change).
		if(useNoverify)
			extraArgs++; // An extra arg added for '-noverify' flag (if number changes below, this must change).
		
		boolean useExpressionTracing = "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACING)); //$NON-NLS-1$
		long expressionTracingThreshold = -1;
		if (useExpressionTracing) {
			extraArgs++;
			String thresholdString = Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyLaunchSupport.EXPRESSION_TRACEING_TIMER_THRESHOLD);
			if (thresholdString != null) {
				try {
					expressionTracingThreshold = Long.valueOf(thresholdString).longValue();
					extraArgs++;
				} catch (NumberFormatException e) {
				}
			}
		}
		
		List javaLibPaths = controller.getFinalJavaLibraryPath();
		int existingLibpaths = -1;
		if (!javaLibPaths.isEmpty()) {
			// first need to see if java lib path also specified in standard args by someone configuring the configuration by hand.
			for (int i = 0; i < evmArgs.length; i++) {
				if (evmArgs[i].startsWith("-Djava.library.path")) { //$NON-NLS-1$
					// We found one already here, save the spot so we update it later.
					existingLibpaths = i;
					break;
				}
			}
			if (existingLibpaths == -1)
				++extraArgs;	// Need to have room for one more.
		}
		
		String[] cvmArgs = new String[evmArgs.length + extraArgs];
		System.arraycopy(evmArgs, 0, cvmArgs, extraArgs, evmArgs.length);	// Put existing into new list at the end.		
		
		int cvmArgsCount=0;
		cvmArgs[cvmArgsCount++] = "-Dproxyvm.registryKey=" + registryKey; //$NON-NLS-1$
		cvmArgs[cvmArgsCount++] = "-Dproxyvm.masterPort=" + String.valueOf(masterServerPort); //$NON-NLS-1$
		cvmArgs[cvmArgsCount++] = "-Dproxyvm.bufsize=" + bufSize; //$NON-NLS-1$
		cvmArgs[cvmArgsCount++] = "-Dproxyvm.servername=" + name; //$NON-NLS-1$
		
		if(useNoverify)
			cvmArgs[cvmArgsCount++] = "-noverify"; //$NON-NLS-1$
		
		if (useExpressionTracing) {
			cvmArgs[cvmArgsCount++] = "-D"+ExpressionCommands.EXPRESSIONTRACE+"=true"; //$NON-NLS-1$ //$NON-NLS-2$
			if (expressionTracingThreshold != -1)
				cvmArgs[cvmArgsCount++] = "-D"+ExpressionCommands.EXPRESSIONTRACE_TIMER_THRESHOLD+'='+String.valueOf(expressionTracingThreshold); //$NON-NLS-1$
		}

		// If in debug mode, we need to find a port for it to use.
		int dport = -1;
		if (debugMode) {
			dport = findUnusedLocalPort("localhost", 5000, 15000, new int[0]); //$NON-NLS-1$
			cvmArgs[cvmArgsCount++] = "-Djava.compiler=NONE"; //$NON-NLS-1$
			cvmArgs[cvmArgsCount++] = "-Xdebug"; //$NON-NLS-1$
			cvmArgs[cvmArgsCount++] = "-Xnoagent"; //$NON-NLS-1$
			cvmArgs[cvmArgsCount++] = "-Xrunjdwp:transport=dt_socket,server=y,address=" + dport; //$NON-NLS-1$
		}
		
		if (!javaLibPaths.isEmpty()) {
			StringBuffer appendTo = null;
			if (existingLibpaths != -1) {
				appendTo = new StringBuffer(evmArgs[existingLibpaths]); 
				appendTo.append(File.pathSeparatorChar);	// Plus a separator so we can append
			} else 
				appendTo = new StringBuffer("-Djava.library.path="); //$NON-NLS-1$
			String [] libPaths = ProxyLaunchSupport.convertURLsToStrings((URL[]) javaLibPaths.toArray(new URL[javaLibPaths.size()]));
			for (int i = 0; i < libPaths.length; i++) {
				if (i != 0)
					appendTo.append(File.pathSeparator);
				appendTo.append(libPaths[i]);
			}
			if (existingLibpaths != -1)
				cvmArgs[extraArgs+existingLibpaths] = appendTo.toString();
			else
				cvmArgs[extraArgs-1] = appendTo.toString();
		}

		runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
		runConfig.setEnvironment(envp);
		runConfig.setVMArguments(cvmArgs);
		runConfig.setWorkingDirectory(workingDirName);
		runConfig.setVMSpecificAttributesMap(vmAttributesMap);

		// Bootpath
		runConfig.setBootClassPath(getBootpath(configuration));

		// check for cancellation
		if (pm.isCanceled())
			return;
		pm.worked(100);

		// set the default source locator if required
		setDefaultSourceLocator(launch, configuration);

		// Launch the configuration - 1 unit of work
		runner.run(runConfig, launch, new SubProgressMonitor(pm, 100));

		// check for cancellation
		if (pm.isCanceled())
			return;

		IProcess[] processes = launch.getProcesses();
		IProcess process = processes[0]; // There is only one.
		// Check if it is already terminated. If it is, then there was a bad error, so just
		// print out the results from it.
		if (process.isTerminated()) {
			IStreamsProxy stProxy = process.getStreamsProxy();
			// Using a printWriter for println capability, but it needs to be on another
			// writer, which will be string
			java.io.StringWriter s = new java.io.StringWriter();
			java.io.PrintWriter w = new java.io.PrintWriter(s);

			w.println(ProxyRemoteMessages.VM_TERMINATED_INFO_); 
			w.println(ProxyRemoteMessages.VM_TERMINATED_LINE1); 
			w.println(stProxy.getErrorStreamMonitor().getContents());
			w.println(ProxyRemoteMessages.VM_TERMINATED_LINE2); 
			w.println(stProxy.getOutputStreamMonitor().getContents());
			w.println(ProxyRemoteMessages.VM_TERMINATED_LINE3); 
			w.close();

			String msg = MessageFormat.format(ProxyRemoteMessages.Proxy_Terminated_too_soon_ERROR_, new Object[] { name }); 
			dh.displayErrorMessage(ProxyRemoteMessages.Proxy_Error_Title, msg); 
			throw new CoreException(
				new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, s.toString(), null));
		} else {
			final String traceName = name;
			IStreamsProxy fStreamsProxy = process.getStreamsProxy();

			/**
			 * StreamListener. Should not be created if ProxyPlugin logger is not logging the requested level.
			 * 
			 * @since 1.1.0
			 */
			class StreamListener implements IStreamListener {
				String tracePrefix;
				Level level;
				Job printJob;	// Job to try to gather printing together.
				Logger logger;
				StringBuffer gatheredText = new StringBuffer(100);
				{
					logger = ProxyPlugin.getPlugin().getLogger();
					printJob = new Job("") { //$NON-NLS-1$

						protected IStatus run(IProgressMonitor monitor) {
							monitor.beginTask(ProxyRemoteMessages.LocalProxyLaunchDelegate_Monitor_PrintRemoteTrace_Text, 1); 
							while(true) {
								String output = null;
								synchronized (gatheredText) {
									if (gatheredText.length() <= tracePrefix.length())
										break;	// We've reached the end, no more to print.
									output = gatheredText.toString();
									gatheredText.setLength(tracePrefix.length());	// Reset the length to the prefix.
								}
								logger.log(output, level);
							}
							monitor.done();
							return Status.OK_STATUS;
						}
					};
					printJob.setPriority(Job.SHORT);
					printJob.setSystem(true);
				}
				
				public StreamListener(String type, Level level, Logger logger) {
					tracePrefix = traceName + ':' + type + '>' + System.getProperty("line.separator"); //$NON-NLS-1$
					gatheredText.append(tracePrefix);
					this.level = level;
					this.logger = logger;
				}

				public void streamAppended(String newText, IStreamMonitor monitor) {
					synchronized(gatheredText) {
						gatheredText.append(newText);
					}
					printJob.schedule(100L);	// Wait tenth of second to gather as much as can together.
				}
			};

			Logger logger = ProxyPlugin.getPlugin().getLogger();
			if (logger.isLoggingLevel(Level.WARNING)) {
				// Always listen to System.err output if we are at least logging warnings.
				IStreamMonitor monitor = fStreamsProxy.getErrorStreamMonitor();
				if (monitor != null)
					monitor.addListener(new StreamListener("err", Level.WARNING, logger)); //$NON-NLS-1$
			}

			// If debug trace is requested, then attach trace listener for System.out
			// Expression tracing requires debug trace too because it prints to sysout. However, it requesting expressionTracing, change logging level to INFO,
			// we want them to show if this true. It is confusing to also have to change logging level in .options file.
			if (useExpressionTracing)
				if (!logger.isLoggingLevel(Level.INFO))
					logger.setLevel(Level.INFO);
			if (useExpressionTracing || "true".equalsIgnoreCase(Platform.getDebugOption(ProxyPlugin.getPlugin().getBundle().getSymbolicName() + ProxyRemoteUtil.DEBUG_VM_TRACEOUT))) { //$NON-NLS-1$
				// Want to trace the output of the remote vm's. And we are logging at least level info.
				if (logger.isLoggingLevel(Level.INFO)) {
					IStreamMonitor monitor = fStreamsProxy.getOutputStreamMonitor();
					if (monitor != null)
						monitor.addListener(new StreamListener("out", Level.INFO, logger)); //$NON-NLS-1$							
				}							
			}
		}

		// If in debug mode, tester must start debugger before going on.
		if (debugMode) {
			if (!dh.promptPort(dport)) {
				process.terminate();
				throw new CoreException(
					new Status(
						IStatus.WARNING,
						ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
						0,
						"Debugger attach canceled", //$NON-NLS-1$
						null));
			}
		}

		// Now set up the registry.
		registry.initializeRegistry(process);
		new REMStandardBeanTypeProxyFactory(registry);
		new REMStandardBeanProxyFactory(registry);
		new REMMethodProxyFactory(registry);

		if (debugMode || REMProxyFactoryRegistry.fGlobalNoTimeouts)
			registry.fNoTimeouts = true;
		if (configuration.getAttribute(IProxyConstants.ATTRIBUTE_AWT_SWING, true))
			REMRegisterAWT.registerAWT(registry);

		launchInfo.resultRegistry = registry;

		pm.done();
		TimerTests.basicTest.stopStep(stepId);
	}

	/**
	 * @param controller
	 * @param info 
	 * @throws CoreException
	 * 
	 * @since 1.0.2
	 */
	private void addInFragmentLibraries(IConfigurationContributionController controller, IConfigurationContributionInfo info) throws CoreException {
		IPDEContributeClasspath instance = IPDEContributeClasspath.INSTANCE;
		if (instance != null) {
			instance.getPDEContributions(controller, info);
		}
	}

	// Utilities to find the free port
	private static final Random fgRandom = new Random(System.currentTimeMillis());

	private static int findUnusedLocalPort(String host, int searchFrom, int searchTo, int[] exclude) {
		for (int i = 0; i < 10; i++) {
			int port = 0;
			newport : while (true) {
				port = getRandomPort(searchFrom, searchTo);
				if (exclude != null)
					for (int e = 0; e < exclude.length; e++)
						if (port == exclude[e])
							continue newport;
				break;
			}
			try {
				new Socket(host, port);
			} catch (ConnectException e) {
				return port;
			} catch (IOException e) {
			}
		}
		return -1;
	}

	private static int getRandomPort(int low, int high) {
		return (int) (fgRandom.nextFloat() * (high - low)) + low;
	}
	
	private String[][] getBootpathExt(Map vmMap) {
	    String[][] ext = new String[3][];
	    if (vmMap != null) {
		    ext[0] = (String[]) vmMap.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_PREPEND);
		    ext[1] = (String[]) vmMap.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH);
		    ext[2] = (String[]) vmMap.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_APPEND);
	    }
	    return ext;
	}
	

}
