/*******************************************************************************
 * Copyright (c) 2000, 2014 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
 *     Nina Rinskaya
 *     		Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=172820.
 *******************************************************************************/
package org.eclipse.jdt.core.tests.runtime;

import java.io.*;
import java.util.*;

import org.eclipse.jdt.core.tests.util.Util;

/**
 * The root of the VM launchers that launch VMs on the same machine.
 * <p>
 * A local VM launcher has the following limitations:
 * <ul>
 *   <li>It can only retrieve the running virtual machines that it has launched. So if
 *       a client is using 2 instances of <code>LocalVMLauncher</code>, each of these
 *       instances will be able to retrieve only a part of the running VMs.
 * </ul>
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class LocalVMLauncher implements RuntimeConstants {

	/**
	 * Whether the target has a file system and thus whether it supports writing
	 * class files to disk. See org.eclipse.jdt.core.tests.eval.target.CodeSnippetRunner for more
	 * information.
	 */
	public static final boolean TARGET_HAS_FILE_SYSTEM = true;
	public static final String REGULAR_CLASSPATH_DIRECTORY = "regularPath";
	public static final String BOOT_CLASSPATH_DIRECTORY = "bootPath";

	protected String[] bootPath;
	protected String[] classPath;
	protected int debugPort = -1;
	protected int evalPort = -1;
	protected String evalTargetPath;
	protected String[] programArguments;
	protected String programClass;
	protected Vector runningVMs = new Vector(); // a Vector of LocalVirtualMachine
	protected String[] vmArguments;
	protected String vmPath;

/**
 * Returns a launcher that will launch the same kind of VM that is currently running
 */
public static LocalVMLauncher getLauncher() {
	final String vmName = System.getProperty("java.vm.name");
	if ("J9".equals(vmName)) {
		return new J9VMLauncher();
	}
	if (vmName != null && vmName.indexOf("JRockit") != -1) {
		return new JRockitVMLauncher();
	}
	final String osName = System.getProperty("os.name");
	if (osName.startsWith("Mac")) {
		return new MacVMLauncher();
	}
	File file = new File(Util.getJREDirectory() + "/lib/rt.jar");
	if (file.exists()) {
		return new StandardVMLauncher();
	}
	if ("IBM J9SE VM".equals(vmName)) {
		return new SideCarJ9VMLauncher();
	}
	if ("DRLVM".equals(vmName)) {
		return new DRLVMLauncher();
	}
	return new SideCarVMLauncher();
}
/**
 * Builds the actual class path that is going to be passed to the VM.
 */
protected String buildClassPath() {
	StringBuffer classPathString = new StringBuffer();
	char pathSeparator = File.pathSeparatorChar;

	// Add jar support if in evaluation mode
	if (this.evalPort != -1) {
		classPathString.append(new File(this.evalTargetPath, SUPPORT_ZIP_FILE_NAME).getPath());
		classPathString.append(pathSeparator);
	}

	// Add class path given by client
	if (this.classPath != null) {
		int length = this.classPath.length;
		for (int i = 0; i < length; i++){
			classPathString.append(this.classPath[i]);
			classPathString.append(pathSeparator);
		}
	}

	// Add regular classpath directory if needed
	if (this.evalPort != -1 && TARGET_HAS_FILE_SYSTEM) {
		classPathString.append(this.evalTargetPath);
		classPathString.append(File.separatorChar);
		classPathString.append(REGULAR_CLASSPATH_DIRECTORY);
	}

	return classPathString.toString();
}
/**
 * Launches the VM by exec'ing the command line and returns the resulting Process.
 */
protected Process execCommandLine() throws TargetException {
	// Check that the VM path has been specified
	if (this.vmPath == null) {
		throw new TargetException("Path to the VM has not been specified");
	}

	// Check that the program class has been specified if not in evaluation mode
	if ((this.programClass == null) && (this.evalPort == -1)) {
		throw new TargetException("Program class has not been specified");
	}

	// Launch VM
	Process vmProcess= null;
	try {
		// Use Runtime.exec(String[]) with tokens because Runtime.exec(String) with commandLineString
		// does not properly handle spaces in arguments on Unix/Linux platforms.
		String[] commandLine = getCommandLine();

		// DEBUG
		/*for (int i = 0; i < commandLine.length; i++) {
			System.out.print(commandLine[i] + " ");
		}
		System.out.println();
		*/

		vmProcess= Runtime.getRuntime().exec(commandLine);
	} catch (IOException e) {
		throw new TargetException("Error launching VM at " + this.vmPath);
	}
	return vmProcess;
}
/**
 * Returns the boot class path used when a VM is launched.
 */
public String[] getBootClassPath() {
	return this.bootPath;
}
/**
 * Returns the class path used when a VM is launched.
 */
public String[] getClassPath() {
	return this.classPath;
}
/**
 * Returns the command line which will be used to launch the VM.
 * The segments are in the following order:
 * <p><ul>
 * <li> VM path,
 * <li> VM arguments,
 * <li> the class path,
 * <li> the program class
 * <li> the program arguments
 * </ul>
 */
public abstract String[] getCommandLine();
/**
 * Returns the debug port, or -1 if debug mode is disabled.
 * The default is -1.
 */
public int getDebugPort() {
	return this.debugPort;
}
/**
 * Returns the evaluation port for evaluation support.
 * The default is -1, indicating no evaluation support.
 *
 * @see #setEvalPort(int)
 */
public int getEvalPort() {
	return this.evalPort;
}
/**
 * Returns the evaluation target path for evaluation support.
 *
 * @see #setEvalTargetPath(String)
 */
public String getEvalTargetPath() {
	return this.evalTargetPath;
}
/**
 * Returns the arguments passed to the program class.
 * Returns null if the VM is being launched for evaluation support only.
 */
public String[] getProgramArguments() {
	if (this.evalPort != -1) {
		return null;
	}
	return this.programArguments;
}
/**
 * Returns the dot-separated, fully qualified name of the class to run.
 * It must implement main(String[] args).
 * Returns null if the VM is being launched for evaluation support only.
 */
public String getProgramClass() {
	if (this.evalPort != -1) {
		return null;
	}
	return this.programClass;
}
/**
 * Returns all the target VMs that are running at this launcher's target
 * address.
 * Note that these target VMs may or may not have been launched by this
 * launcher.
 * Note also that if the list of running VMs doesn't change on the target,
 * two calls to this method return VMs that are equal.
 *
 * @return the list of running target VMs
 */
public LocalVirtualMachine[] getRunningVirtualMachines() {
	// Select the VMs that are actually running
	Vector actuallyRunning = new Vector();
	Enumeration en = this.runningVMs.elements();
	while (en.hasMoreElements()) {
		LocalVirtualMachine vm = (LocalVirtualMachine)en.nextElement();
		if (vm.isRunning())
			actuallyRunning.addElement(vm);
	}
	this.runningVMs = actuallyRunning;

	// Return the running VMs
	int size = actuallyRunning.size();
	LocalVirtualMachine[] result = new LocalVirtualMachine[size];
	for (int i=0; i<size; i++)
		result[i] = (LocalVirtualMachine)actuallyRunning.elementAt(i);
	return result;
}
/**
 * Returns the address of the target where this launcher runs the target VMs. The format
 * of this address is transport specific.
 * For example, a VM launcher using a TCP/IP transport returns target addresses looking like:
 * <code>"localhost:2010"</code>, or <code>"joe.ibm.com"</code>.
 *
 * @return transport specific address of the target
 */
public String getTargetAddress() {
	return "localhost";
}
/**
 * Returns the VM-specific arguments. This does not include:
 * <p><ul>
 * <li>the VM path
 * <li>the class path or the boot class path
 * <li>the program class or program arguments
 * </ul>
 */
public String[] getVMArguments() {
	return this.vmArguments;
}
/**
 * Returns the path on disk of the VM to launch.
 */
public String getVMPath() {
	return this.vmPath;
}
/**
 * Initializes this context's target path by copying the jar file for the code snippet support
 * and by creating the 2 directories that will contain the code snippet classes (see TARGET_HAS_FILE_SYSTEM).
 * Add the code snipport root class to the boot path directory so that code snippets can be run in
 * java.* packages
 *
 * @throws TargetException if the path could not be initialized with the code snippet support
 */
protected void initTargetPath() throws TargetException {
	// create directories
	File directory = new File(this.evalTargetPath);
	directory.mkdirs();
	if (!directory.exists()) {
		throw new TargetException("Could not create directory " + this.evalTargetPath);
	}
	if (TARGET_HAS_FILE_SYSTEM) {
		File classesDirectory = new File(directory, REGULAR_CLASSPATH_DIRECTORY);
		classesDirectory.mkdir();
		if (!classesDirectory.exists()) {
			throw new TargetException("Could not create directory " + classesDirectory.getPath());
		}
		File bootDirectory = new File(directory, BOOT_CLASSPATH_DIRECTORY);
		bootDirectory.mkdir();
		if (!bootDirectory.exists()) {
			throw new TargetException("Could not create directory " + bootDirectory.getPath());
		}
		/*
		// add the code snippet root class to the boot path directory
		InputStream in = null;
		try {
			in = EvaluationContext.class.getResourceAsStream("/" + SUPPORT_ZIP_FILE_NAME);
			ZipInputStream zip = new ZipInputStream(in);
			String rootClassFileName = ROOT_FULL_CLASS_NAME.replace('.', '/') + ".class";
			while (true) {
				ZipEntry entry = zip.getNextEntry();
				if (entry.getName().equals(rootClassFileName)) {
					// read root class file contents
					int size = (int)entry.getSize();
					byte[] buffer = new byte[size];
					int totalRead = 0;
					int read = 0;
					while (totalRead < size) {
						read = zip.read(buffer, totalRead, size - totalRead);
						if (read != -1) {
							totalRead += read;
						}
					}
					// write root class file contents
					FileOutputStream out = null;
					try {
						File rootFile = new File(bootDirectory, rootClassFileName.replace('/', File.separatorChar));
						File parent = new File(rootFile.getParent());
						parent.mkdirs();
						out = new FileOutputStream(rootFile);
						out.write(buffer);
						out.close();
					} catch (IOException e) {
						e.printStackTrace();
						if (out != null) {
							try {
								out.close();
							} catch (IOException e2) {
							}
						}
					}
					break;
				}
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
			if (in != null) {
				try {
					in.close();
				} catch (IOException e2) {
				}
			}
		}*/
	}

	// copy jar file
	InputStream in = null;
	FileOutputStream out = null;
	try {
		in = getClass().getResourceAsStream("/" + SUPPORT_ZIP_FILE_NAME);
		if (in == null) {
			throw new TargetException("Could not find resource /" + SUPPORT_ZIP_FILE_NAME);
		}
		int bufferLength = 1024;
		byte[] buffer = new byte[bufferLength];
		File file = new File(directory, SUPPORT_ZIP_FILE_NAME);
		out = new FileOutputStream(file);
		int read = 0;
		while (read != -1) {
			read = in.read(buffer, 0, bufferLength);
			if (read != -1) {
				out.write(buffer, 0, read);
			}
		}
	} catch (IOException e) {
		throw new TargetException("IOException while copying " + SUPPORT_ZIP_FILE_NAME + ": " + e.getMessage());
	} finally {
		if (in != null) {
			try {
				in.close();
			} catch (IOException e) {
			}
		}
		if (out != null) {
			try {
				out.close();
			} catch (IOException e) {
			}
		}
	}
}
/**
 * Launches a new target VM with the registered arguments.
 * This operation returns once a new target VM has been launched.
 *
 * @exception TargetException if the target VM could not be launched.
 */
public LocalVirtualMachine launch() throws TargetException {
	// evaluation mode
	if (this.evalTargetPath != null) {
		// init target path
		initTargetPath();
	}

	// launch VM
	LocalVirtualMachine vm;
	Process p = execCommandLine();
	vm = new LocalVirtualMachine(p, this.debugPort, this.evalTargetPath);

	// TBD: Start reading VM stdout and stderr right away otherwise this may prevent the connection
	//		from happening.

	// add VM to list of known running VMs
	this.runningVMs.addElement(vm);
	return vm;
}
/**
 * Sets the boot class path used when a VM is launched.
 */
public void setBootClassPath(java.lang.String[] bootClassPath) {
	this.bootPath = bootClassPath;
}
/**
 * Sets the class path used when a VM is launched.
 */
public void setClassPath(String[] classPath) {
	this.classPath = classPath;
}
/**
 * Sets the debug port to use for debug support.
 * Specify -1 to disable debug mode.
 */
public void setDebugPort(int debugPort) {
	this.debugPort = debugPort;
}
/**
 * Sets the evaluation port to use for evaluation support.
 * Setting the port enables evaluation support.
 * Specify null to disable evaluation support.
 */
public void setEvalPort(int evalPort) {
	this.evalPort = evalPort;
}
/**
 * Sets the evaluation target path to use for evaluation support.
 */
public void setEvalTargetPath(String evalTargetPath) {
	this.evalTargetPath = evalTargetPath;
}
/**
 * Sets the arguments passed to the program class.
 * This is ignored if the VM is being launched for evaluation support only.
 */
public void setProgramArguments(String[] args) {
	this.programArguments = args;
}
/**
 * Sets the dot-separated, fully qualified name of the class to run.
 * It must implement main(String[] args).
 * This is ignored if the VM is being launched for evaluation support only.
 */
public void setProgramClass(String programClass) {
	this.programClass = programClass;
}
/**
 * Sets the VM-specific arguments. This does not include:
 * <p><ul>
 * <li>the VM path
 * <li>the class path or the boot class path
 * <li>the program class or program arguments
 * </ul>
 */
public void setVMArguments(String[] args) {
	this.vmArguments = args;
}
/**
 * Sets the path on disk of the VM to launch.
 */
public void setVMPath(String vmPath) {
	this.vmPath = vmPath;
}
}
