/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.util;

import org.eclipse.jdt.core.tests.runtime.*;
import java.io.*;
import java.net.*;
/**
 * Verifies that the .class files resulting from a compilation can be loaded
 * in a VM and that they can be run.
 */
public class TestVerifier {
	public String failureReason;
	
	boolean reuseVM = true;
	String[] classpathCache;
	LocalVirtualMachine vm;
	StringBuffer outputBuffer;
	StringBuffer errorBuffer;
	Socket socket;
public TestVerifier(boolean reuseVM) {
	this.reuseVM = reuseVM;
}
private boolean checkBuffers(String errorString, String outputString, String sourceFileName, String expectedSuccessOutputString) {

	if (errorString.length() > 0) {
		this.failureReason =
			"Unexpected target error running resulting class file for "
				+ sourceFileName
				+ ":\n"
				+ errorString;
		return false;
	}
	String platformIndependantOutputString = Util.convertToIndependantLineDelimiter(outputString);
	if (expectedSuccessOutputString != null && (platformIndependantOutputString.indexOf(expectedSuccessOutputString) == -1
		|| expectedSuccessOutputString.length() == 0 && platformIndependantOutputString.length() != 0)) {
		System.out.println(Util.displayString(platformIndependantOutputString, 2));
		this.failureReason =
			"Unexpected output running resulting class file for "
				+ sourceFileName
				+ ":\n"
				+ "--[START]--\n"
				+ outputString
				+ "---[END]---\n";
		return false;
	}
	
	return true;
}

private boolean checkBuffersThrowingError(String errorString, String sourceFileName, String expectedSuccessOutputString) {

	if (errorString.length() > 0 && errorString.indexOf(expectedSuccessOutputString) != -1) {
		return true;
	}
	
	this.failureReason =
		"Expected error not thrown for "
			+ sourceFileName
			+ ":\n"
			+ expectedSuccessOutputString;
	return false;
}

private void compileVerifyTests(String verifierDir) {
	String fullyQualifiedName = VerifyTests.class.getName();

	int lastDot = fullyQualifiedName.lastIndexOf('.');
	String packageName = fullyQualifiedName.substring(0, lastDot);
	String simpleName = fullyQualifiedName.substring(lastDot + 1);
	
	String dirName = verifierDir.replace('\\', '/') + "/" + packageName.replace('.', '/');
	File dir = new File(dirName.replace('/', File.separatorChar));
	if (!dir.exists() && !dir.mkdirs()) {
		System.out.println("Could not create " + dir);
		return;
	}
	String fileName = dir + File.separator + simpleName + ".java";
	Util.writeToFile(this.getVerifyTestsCode(), fileName);
	org.eclipse.jdt.internal.compiler.batch.Main.compile("\"" + fileName + "\" -d \"" + verifierDir + "\" -classpath \"" + Util.getJavaClassLib() + "\"");
}
public void execute(String className, String[] classpaths) {
	this.outputBuffer = new StringBuffer();
	this.errorBuffer = new StringBuffer();
	
	launchAndRun(className, classpaths, null, null);
}
protected void finalize() throws Throwable {
	this.shutDown();
}
public String getExecutionOutput(){
	return outputBuffer.toString();
}

public String getExecutionError(){
	return errorBuffer.toString();
}
/**
 * Returns the code of the VerifyTests class.
 *
 * To generate:
 *	- export VerifyTests to c:/temp/test
 *  - inspect org.eclipse.jdt.core.tests.util.Util.fileContentToDisplayString("c:/temp/test/org/eclipse/jdt/core/tests/util/VerifyTests.java", 2)
 */
private String getVerifyTestsCode() {
	return 
		"package org.eclipse.jdt.core.tests.util;\n" + 
		"import java.lang.reflect.*;\n" + 
		"import java.io.*;\n" + 
		"import java.net.*;\n" + 
		"import java.util.*;\n" + 
		"public class VerifyTests {\n" + 
		"	int portNumber;\n" + 
		"	Socket socket;\n" + 
		"/**\n" + 
		" * NOTE: Code copied from junit.util.TestCaseClassLoader.\n" + 
		" *\n" + 
		" * A custom class loader which enables the reloading\n" + 
		" * of classes for each test run. The class loader\n" + 
		" * can be configured with a list of package paths that\n" + 
		" * should be excluded from loading. The loading\n" + 
		" * of these packages is delegated to the system class\n" + 
		" * loader. They will be shared across test runs.\n" + 
		" * <p>\n" + 
		" * The list of excluded package paths is specified in\n" + 
		" * a properties file \"excluded.properties\" that is located in \n" + 
		" * the same place as the TestCaseClassLoader class.\n" + 
		" * <p>\n" + 
		" * <b>Known limitation:</b> the VerifyClassLoader cannot load classes\n" + 
		" * from jar files.\n" + 
		" */\n" + 
		"public class VerifyClassLoader extends ClassLoader {\n" + 
		"	/** scanned class path */\n" + 
		"	private String[] fPathItems;\n" + 
		"	\n" + 
		"	/** excluded paths */\n" + 
		"	private String[] fExcluded= {};\n" + 
		"	/**\n" + 
		"	 * Constructs a VerifyClassLoader. It scans the class path\n" + 
		"	 * and the excluded package paths\n" + 
		"	 */\n" + 
		"	public VerifyClassLoader() {\n" + 
		"		super();\n" + 
		"		String classPath= System.getProperty(\"java.class.path\");\n" + 
		"		String separator= System.getProperty(\"path.separator\");\n" + 
		"		\n" + 
		"		// first pass: count elements\n" + 
		"		StringTokenizer st= new StringTokenizer(classPath, separator);\n" + 
		"		int i= 0;\n" + 
		"		while (st.hasMoreTokens()) {\n" + 
		"			st.nextToken();\n" + 
		"			i++;\n" + 
		"		}\n" + 
		"		// second pass: split\n" + 
		"		fPathItems= new String[i];\n" + 
		"		st= new StringTokenizer(classPath, separator);\n" + 
		"		i= 0;\n" + 
		"		while (st.hasMoreTokens()) {\n" + 
		"			fPathItems[i++]= st.nextToken();\n" + 
		"		}\n" + 
		"	}\n" + 
		"	public java.net.URL getResource(String name) {\n" + 
		"		return ClassLoader.getSystemResource(name);\n" + 
		"	}\n" + 
		"	public InputStream getResourceAsStream(String name) {\n" + 
		"		return ClassLoader.getSystemResourceAsStream(name);\n" + 
		"	}\n" + 
		"	protected boolean isExcluded(String name) {\n" + 
		"		// exclude the \"java\" packages.\n" + 
		"		// They always need to be excluded so that they are loaded by the system class loader\n" + 
		"		if (name.startsWith(\"java\"))\n" + 
		"			return true;\n" + 
		"			\n" + 
		"		// exclude the user defined package paths\n" + 
		"		for (int i= 0; i < fExcluded.length; i++) {\n" + 
		"			if (name.startsWith(fExcluded[i])) {\n" + 
		"				return true;\n" + 
		"			}\n" + 
		"		}\n" + 
		"		return false;	\n" + 
		"	}\n" + 
		"	public synchronized Class loadClass(String name, boolean resolve)\n" + 
		"		throws ClassNotFoundException {\n" + 
		"			\n" + 
		"		Class c= findLoadedClass(name);\n" + 
		"		if (c != null)\n" + 
		"			return c;\n" + 
		"		//\n" + 
		"		// Delegate the loading of excluded classes to the\n" + 
		"		// standard class loader.\n" + 
		"		//\n" + 
		"		if (isExcluded(name)) {\n" + 
		"			try {\n" + 
		"				c= findSystemClass(name);\n" + 
		"				return c;\n" + 
		"			} catch (ClassNotFoundException e) {\n" + 
		"				// keep searching\n" + 
		"			}\n" + 
		"		}\n" + 
		"		if (c == null) {\n" + 
		"			File file= locate(name);\n" + 
		"			if (file == null)\n" + 
		"				throw new ClassNotFoundException();\n" + 
		"			byte data[]= loadClassData(file);\n" + 
		"			c= defineClass(name, data, 0, data.length);\n" + 
		"		}\n" + 
		"		if (resolve) \n" + 
		"			resolveClass(c);\n" + 
		"		return c;\n" + 
		"	}\n" + 
		"	private byte[] loadClassData(File f) throws ClassNotFoundException {\n" + 
		"		try {\n" + 
		"			//System.out.println(\"loading: \"+f.getPath());\n" + 
		"			FileInputStream stream= new FileInputStream(f);\n" + 
		"			\n" + 
		"			try {\n" + 
		"				byte[] b= new byte[stream.available()];\n" + 
		"				stream.read(b);\n" + 
		"				stream.close();\n" + 
		"				return b;\n" + 
		"			}\n" + 
		"			catch (IOException e) {\n" + 
		"				throw new ClassNotFoundException();\n" + 
		"			}\n" + 
		"		}\n" + 
		"		catch (FileNotFoundException e) {\n" + 
		"			throw new ClassNotFoundException();\n" + 
		"		}\n" + 
		"	}\n" + 
		"	/**\n" + 
		"	 * Locate the given file.\n" + 
		"	 * @return Returns null if file couldn\'t be found.\n" + 
		"	 */\n" + 
		"	private File locate(String fileName) { \n" + 
		"		fileName= fileName.replace(\'.\', \'/\')+\".class\";\n" + 
		"		File path= null;\n" + 
		"		\n" + 
		"		if (fileName != null) {\n" + 
		"			for (int i= 0; i < fPathItems.length; i++) {\n" + 
		"				path= new File(fPathItems[i], fileName);\n" + 
		"				if (path.exists())\n" + 
		"					return path;\n" + 
		"			}\n" + 
		"		}\n" + 
		"		return null;\n" + 
		"	}\n" + 
		"}\n" + 
		"	\n" + 
		"public void loadAndRun(String className) throws Throwable {\n" + 
		"	//System.out.println(\"Loading \" + className + \"...\");\n" + 
		"	Class testClass = new VerifyClassLoader().loadClass(className);\n" + 
		"	//System.out.println(\"Loaded \" + className);\n" + 
		"	try {\n" + 
		"		Method main = testClass.getMethod(\"main\", new Class[] {String[].class});\n" + 
		"		//System.out.println(\"Running \" + className);\n" + 
		"		main.invoke(null, new Object[] {new String[] {}});\n" + 
		"		//System.out.println(\"Finished running \" + className);\n" + 
		"	} catch (NoSuchMethodException e) {\n" + 
		"		return;\n" + 
		"	} catch (InvocationTargetException e) {\n" + 
		"		throw e.getTargetException();\n" + 
		"	}\n" + 
		"}\n" + 
		"public static void main(String[] args) throws IOException {\n" + 
		"	VerifyTests verify = new VerifyTests();\n" + 
		"	verify.portNumber = Integer.parseInt(args[0]);\n" + 
		"	verify.run();\n" + 
		"}\n" + 
		"public void run() throws IOException {\n" + 
		"	ServerSocket server = new ServerSocket(this.portNumber);\n" + 
		"	this.socket = server.accept();\n" + 
		"	this.socket.setTcpNoDelay(true);\n" + 
		"	server.close();\n" + 
		"	DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" + 
		"	final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" + 
		"	while (true) {\n" + 
		"		final String className = in.readUTF();\n" + 
		"		Thread thread = new Thread() {\n" + 
		"			public void run() {\n" + 
		"				try {\n" + 
		"					loadAndRun(className);\n" + 
		"					out.writeBoolean(true);\n" + 
		"					System.err.println(VerifyTests.class.getName());\n" + 
		"					System.out.println(VerifyTests.class.getName());\n" + 
		"				} catch (Throwable e) {\n" + 
		"					e.printStackTrace();\n" + 
		"					try {\n" + 
		"						System.err.println(VerifyTests.class.getName());\n" + 
		"						System.out.println(VerifyTests.class.getName());\n" + 
		"						out.writeBoolean(false);\n" + 
		"					} catch (IOException e1) {\n" + 
		"					}\n" + 
		"				}\n" + 
		"			}\n" + 
		"		};\n" + 
		"		thread.start();\n" + 
		"	}\n" + 
		"}\n" + 
		"}\n";
}
private void launchAndRun(String className, String[] classpaths, String[] programArguments, String[] vmArguments) {
	// we won't reuse the vm, shut the existing one if running
	if (this.vm != null) {
		try {
			vm.shutDown();
		} catch (TargetException e) {
		}
	}
	this.classpathCache = null;

	// launch a new one
	LocalVMLauncher launcher = LocalVMLauncher.getLauncher();
	launcher.setClassPath(classpaths);
	launcher.setVMPath(Util.getJREDirectory());
	if (vmArguments != null) {
		String[] completeVmArguments = new String[vmArguments.length + 1];
		System.arraycopy(vmArguments, 0, completeVmArguments, 1, vmArguments.length);
		completeVmArguments[0] = "-verify";
		launcher.setVMArguments(completeVmArguments);
	} else {
		launcher.setVMArguments(new String[] {"-verify"});
	}
	launcher.setProgramClass(className);
	launcher.setProgramArguments(programArguments);
	Thread outputThread;
	Thread errorThread;
	try {
		this.vm = launcher.launch();
		final InputStream input = this.vm.getInputStream();
		outputThread = new Thread(new Runnable() {
			public void run() {
				try {
					int c = input.read();
					while (c != -1) {
						outputBuffer.append((char) c);
						c = input.read();
					}
				} catch(IOException ioEx) {
				}
			}
		});
		final InputStream errorStream = this.vm.getErrorStream();
		errorThread = new Thread(new Runnable() {
			public void run() {
				try {
					int c = errorStream.read();
					while (c != -1) {
						errorBuffer.append((char) c);
						c = errorStream.read();
					}
				} catch(IOException ioEx) {
				}
			}
		});
		outputThread.start();
		errorThread.start();
	} catch(TargetException e) {
		throw new Error(e.getMessage());
	}

	// wait for vm to shut down by itself
	try {
		outputThread.join(5000);
		errorThread.join(5000);
	} catch (InterruptedException e) {
	}
}
private void launchVerifyTestsIfNeeded(String[] classpaths, String[] vmArguments) {
	// determine if we can reuse the vm
	if (this.vm != null && this.vm.isRunning() && this.classpathCache != null) {
		boolean sameClasspaths = true;
		for (int i = 0; i < classpaths.length; i++) {
			if (!this.classpathCache[i].equals(classpaths[i])) {
				sameClasspaths = false;
				break;
			}
		}
		if (sameClasspaths) {
			return;
		}
	}

	// we could not reuse the vm, shut the existing one if running
	if (this.vm != null) {
		try {
			vm.shutDown();
		} catch (TargetException e) {
		}
	}

	this.classpathCache = classpaths;

	// launch a new one
	LocalVMLauncher launcher = LocalVMLauncher.getLauncher();
	int length = classpaths.length;
	String[] cp = new String[length + 1];
	System.arraycopy(classpaths, 0, cp, 0, length);
	String verifierDir = Util.getOutputDirectory() + File.separator + "verifier";
	this.compileVerifyTests(verifierDir);
	cp[length] = verifierDir;
	launcher.setClassPath(cp);
	launcher.setVMPath(Util.getJREDirectory());
	if (vmArguments != null) {
		String[] completeVmArguments = new String[vmArguments.length + 1];
		System.arraycopy(vmArguments, 0, completeVmArguments, 1, vmArguments.length);
		completeVmArguments[0] = "-verify";
		launcher.setVMArguments(completeVmArguments);
	} else {
		launcher.setVMArguments(new String[] {"-verify"});
	}
	launcher.setProgramClass(VerifyTests.class.getName());
	int portNumber = Util.nextAvailablePortNumber();
	launcher.setProgramArguments(new String[] {Integer.toString(portNumber)});
	try {
		this.vm = launcher.launch();
		final InputStream input = this.vm.getInputStream();
		Thread outputThread = new Thread(new Runnable() {
			public void run() {
				try {
					int c = input.read();
					while (c != -1) {
						outputBuffer.append((char) c);
						c = input.read();
					}
				} catch(IOException ioEx) {
				}
			}
		});
		final InputStream errorStream = this.vm.getErrorStream();
		Thread errorThread = new Thread(new Runnable() {
			public void run() {
				try {
					int c = errorStream.read();
					while (c != -1) {
						errorBuffer.append((char) c);
						c = errorStream.read();
					}
				} catch(IOException ioEx) {
				}
			}
		});
		outputThread.start();
		errorThread.start();
	} catch(TargetException e) {
		throw new Error(e.getMessage());
	}

	// connect to the vm
	this.socket = null;
	boolean isVMRunning = false;
	do {
		try {
			this.socket = new Socket("localhost", portNumber);
			this.socket.setTcpNoDelay(true);
			break;
		} catch (UnknownHostException e) {
		} catch (IOException e) {
		}
		if (this.socket == null) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
			}
			isVMRunning = vm.isRunning();
		}
	} while (this.socket == null && isVMRunning);
	
}
/**
 * Loads and runs the given class.
 * Return whether no exception was thrown while running the class.
 */
private boolean loadAndRun(String className) {
	if (this.socket != null) {
		try {
			DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());
			out.writeUTF(className);
			DataInputStream in = new DataInputStream(this.socket.getInputStream());
			try {
				boolean result = in.readBoolean();
				this.waitForFullBuffers();
				return result;
			} catch (SocketException e) {
				// connection was reset because target program has exited
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return true;
}
public void shutDown() {
	// Close the socket first so that the OS resource has a chance to be freed.
	if (this.socket != null) {
		try {
			this.socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	// Wait for the vm to shut down by itself for 2 seconds. If not succesfull, force the shut down.
	if (this.vm != null) {
		try {
			int retry = 0;
			while (this.vm.isRunning() && (++retry < 20)) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}
			if (this.vm.isRunning()) {
				this.vm.shutDown();
			}
		} catch (TargetException e) {
			e.printStackTrace();
		}
	}
}
/**
 * Verify that the class files created for the given test file can be loaded by
 * a virtual machine.
 */
public boolean verifyClassFiles(String sourceFilePath, String className, String expectedSuccessOutputString, String[] classpaths) {
	return verifyClassFiles(sourceFilePath, className, expectedSuccessOutputString, classpaths, null, null);
}
/**
 * Verify that the class files created for the given test file can be loaded by
 * a virtual machine.
 */
public boolean verifyClassFiles(String sourceFilePath, String className, String expectedSuccessOutputString, String[] classpaths, String[] programArguments, String[] vmArguments) {
	this.outputBuffer = new StringBuffer();
	this.errorBuffer = new StringBuffer();
	if (this.reuseVM && programArguments == null) {
		this.launchVerifyTestsIfNeeded(classpaths, vmArguments);
		this.loadAndRun(className);
	} else {
		this.launchAndRun(className, classpaths, programArguments, vmArguments);
	}
	
	this.failureReason = null;
	return this.checkBuffers(this.errorBuffer.toString(), this.outputBuffer.toString(), sourceFilePath, expectedSuccessOutputString);
}

/**
 * Verify that the class files created for the given test file can be loaded and run with an expected error contained
 * in the expectedSuccessOutputString string.
 */
public boolean verifyClassFilesThrowingError(String sourceFilePath, String className, String expectedSuccessOutputString, String[] classpaths, String[] programArguments, String[] vmArguments) {
	this.outputBuffer = new StringBuffer();
	this.errorBuffer = new StringBuffer();
	if (this.reuseVM && programArguments == null) {
		this.launchVerifyTestsIfNeeded(classpaths, vmArguments);
		this.loadAndRun(className);
	} else {
		this.launchAndRun(className, classpaths, programArguments, vmArguments);
	}
	
	this.failureReason = null;
	return this.checkBuffersThrowingError(this.errorBuffer.toString(), sourceFilePath, expectedSuccessOutputString);
}

/**
 * Wait until there is nothing more to read from the stdout or sterr.
 */
private void waitForFullBuffers() {
	String endString = VerifyTests.class.getName();
	int count = 50;
	int errorEndStringStart = this.errorBuffer.toString().indexOf(endString);
	int outputEndStringStart = this.outputBuffer.toString().indexOf(endString);
	while (errorEndStringStart == -1 || outputEndStringStart == -1) {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
		}
		if (--count == 0) return;
		errorEndStringStart = this.errorBuffer.toString().indexOf(endString);
		outputEndStringStart = this.outputBuffer.toString().indexOf(endString);
	}
	this.errorBuffer.setLength(errorEndStringStart);
	this.outputBuffer.setLength(outputEndStringStart);
}
}
