/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.jdt.internal.junit.runner;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.ArrayList;

import java.util.List;
import junit.extensions.TestDecorator;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestFailure;
import junit.framework.TestListener;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import org.eclipse.jdt.internal.junit.ui.JUnitMessages;

/**
 * A TestRunner that reports results via a socket connection.
 * See MessageIds for more information about the protocl.
 */
public class RemoteTestRunner implements TestListener {
	/**
	 * Holder for information for a rerun request
	 */
	private static class RerunRequest {
		String fClassName;
		String fTestName;
		
		public RerunRequest(String className, String testName) {
			fClassName= className;
			fTestName= testName;
		}
	}
	
	private static final String SUITE_METHODNAME= "suite";	 //$NON-NLS-1$
	/**
	 * The name of the test classes to be executed
	 */
	private String[] fTestClassNames;
	/**
	 * The current test result
	 */
	private TestResult fTestResult;

	/**
	 * The client socket.
	 */
	private Socket fClientSocket;
	/**
	 * Print writer for sending messages
	 */
	private PrintWriter fWriter;
	/**
	 * Reader for incoming messages
	 */
	private BufferedReader fReader;
	/**
	 * Host to connect to, default is the localhost
	 */
	private String fHost= ""; //$NON-NLS-1$
	/**
	 * Port to connect to.
	 */
	private int fPort= -1;
	/**
	 * Is the debug mode enabled?
	 */
	private boolean fDebugMode= false;	
	/**
	 * Keep the test run server alive after a test run has finished.
	 * This allows to rerun tests.
	 */
	private boolean fKeepAlive= false;
	/**
	 * Has the server been stopped
	 */
	private boolean fStopped= false;
	/**
	 * Queue of rerun requests.
	 */
	private List fRerunRequests= new ArrayList(10);
	/**
	 * Reader thread that processes messages from the client.
	 */
	private class ReaderThread extends Thread {
		public ReaderThread() {
			super("ReaderThread"); //$NON-NLS-1$
		}

		public void run(){
			try { 
				String message= null; 
				while (true) { 
					if ((message= fReader.readLine()) != null) {
						
						if (message.startsWith(MessageIds.TEST_STOP)){
							fStopped= true;
							RemoteTestRunner.this.stop();
							synchronized(RemoteTestRunner.this) {
								RemoteTestRunner.this.notifyAll();
							}
							break;
						}
						
						else if (message.startsWith(MessageIds.TEST_RERUN)) {
							String arg= message.substring(MessageIds.MSG_HEADER_LENGTH);
							int c= arg.indexOf(" "); //$NON-NLS-1$
							synchronized(RemoteTestRunner.this) {
								fRerunRequests.add(new RerunRequest(arg.substring(0, c), arg.substring(c+1)));
								RemoteTestRunner.this.notifyAll();
							}
						}
					}
				} 
			} catch (Exception e) {
				RemoteTestRunner.this.stop();
			}
		}
	}	
	
	/** 
	 * The main entry point.
	 * Parameters<pre>
	 * -classnames: the name of the test suite class
     * -host: the host to connect to - default local host
     * -port: the port to connect to, mandatory argument
     * -keepalive: keep the process alive after a test run
     * </pre>
     */
	public static void main(String[] args) {
		RemoteTestRunner testRunServer= new RemoteTestRunner();
		testRunServer.init(args);
		testRunServer.run();
		// fix for 14434
		System.exit(0);
	}
	
	/**
	 * Parse command line arguments. Hook for subclasses to process
	 * additional arguments.
	 */
	protected void init(String[] args) {
		defaultInit(args);		
	}	
	
	/**
	 * The class loader to be used for loading tests.
	 * Subclasses may override to use another class loader.
	 */
	protected ClassLoader getClassLoader() {
		return getClass().getClassLoader();
	}
	
	/**
	 * Process the default arguments.
	 */
	protected final void defaultInit(String[] args) {
		for(int i= 0; i < args.length; i++) {
			if(args[i].toLowerCase().equals("-classnames") || args[i].toLowerCase().equals("-classname")){ //$NON-NLS-1$ //$NON-NLS-2$
				ArrayList list= new ArrayList();
				for (int j= i+1; j < args.length; j++) {
					if (args[j].startsWith("-")) //$NON-NLS-1$
						break;
					list.add(args[j]);
				}
				fTestClassNames= (String[]) list.toArray(new String[list.size()]);
			}	
			else if(args[i].toLowerCase().equals("-testnamefile")) {
				String testNameFile= args[i+1];
				try {
					readTestNames(testNameFile);
				} catch (IOException e) {
					throw new IllegalArgumentException("Cannot read testname file.");		
				}
				i++;
			
			} else if(args[i].toLowerCase().equals("-port")) { //$NON-NLS-1$
				fPort= Integer.parseInt(args[i+1]);
				i++;
			}
			else if(args[i].toLowerCase().equals("-host")) { //$NON-NLS-1$
				fHost= args[i+1];
				i++;
			}
			else if(args[i].toLowerCase().equals("-keepalive")) { //$NON-NLS-1$
				fKeepAlive= true;
			}
			else if(args[i].toLowerCase().equals("-debugging") || args[i].toLowerCase().equals("-debug")){ //$NON-NLS-1$ //$NON-NLS-2$
				fDebugMode= true;
			}
		}
		if(fTestClassNames == null || fTestClassNames.length == 0)
			throw new IllegalArgumentException(JUnitMessages.getString("RemoteTestRunner.error.classnamemissing")); //$NON-NLS-1$

		if (fPort == -1)
			throw new IllegalArgumentException(JUnitMessages.getString("RemoteTestRunner.error.portmissing")); //$NON-NLS-1$
		if (fDebugMode)
			System.out.println("keepalive "+fKeepAlive); //$NON-NLS-1$
	}

	private void readTestNames(String testNameFile) throws IOException {
		BufferedReader br= new BufferedReader(new FileReader(new File(testNameFile)));
		try {
			String line;
			ArrayList list= new ArrayList();
			while ((line= br.readLine()) != null) {
				list.add(line);
			}
			fTestClassNames= (String[]) list.toArray(new String[list.size()]);
		}
		finally {
			br.close();
		}
		if (fDebugMode) {
			System.out.println("Tests:");
			for (int i= 0; i < fTestClassNames.length; i++) {
				System.out.println("    "+fTestClassNames[i]);
			}
		}
	}

	
	/**
	 * Connects to the remote ports and runs the tests.
	 */
	protected void run() {
		if (!connect()) {
			return;
		} 
			
		fTestResult= new TestResult();
		fTestResult.addListener(this);
		runTests(fTestClassNames);
		fTestResult.removeListener(this);
		
		if (fTestResult != null) {
			fTestResult.stop();
			fTestResult= null;
		}
		if (fKeepAlive)
			waitForReruns();
			
		shutDown();
		
	}

	/**
	 * Waits for rerun requests until an explicit stop request
	 */
	private synchronized void waitForReruns() {
		while (!fStopped) {
			try {
				wait();
				if (!fStopped && fRerunRequests.size() > 0) {
					RerunRequest r= (RerunRequest)fRerunRequests.remove(0);
					rerunTest(r.fClassName, r.fTestName);
				}
			} catch (InterruptedException e) {
			}
		}
	}
	
	/**
	 * Returns the Test corresponding to the given suite. 
	 */
	private Test getTest(String suiteClassName) {
		Class testClass= null;
		try {
			testClass= loadSuiteClass(suiteClassName);
		} catch (ClassNotFoundException e) {
			String clazz= e.getMessage();
			if (clazz == null) 
				clazz= suiteClassName;
			runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.classnotfound", clazz)); //$NON-NLS-1$
			return null;
		} catch(Exception e) {
			runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.exception", e.toString() )); //$NON-NLS-1$
			return null;
		}
		Method suiteMethod= null;
		try {
			suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
	 	} catch(Exception e) {
	 		// try to extract a test suite automatically
			return new TestSuite(testClass);
		}
		Test test= null;
		try {
			test= (Test)suiteMethod.invoke(null, new Class[0]); // static method
		} 
		catch (InvocationTargetException e) {
			runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.invoke", e.getTargetException().toString() )); //$NON-NLS-1$
			return null;
		}
		catch (IllegalAccessException e) {
			runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.invoke", e.toString() )); //$NON-NLS-1$
			return null;
		}
		return test;
	}

	protected void runFailed(String message) {
		System.err.println(message);
	}
	
	/**
	 * Loads the test suite class.
	 */
	private Class loadSuiteClass(String className) throws ClassNotFoundException {
		if (className == null) 
			return null;
		return getClassLoader().loadClass(className);
	}
			
	/**
	 * Runs a set of tests.
	 */
	private void runTests(String[] testClassNames) {
		// instantiate all tests
		Test[] suites= new Test[testClassNames.length];
		
		for (int i= 0; i < suites.length; i++) {
			Test test= getTest(testClassNames[i]);
			suites[i]= test;
		}
		
		// count all testMethods and inform ITestRunListeners		
		int count= countTests(suites);
		notifyTestRunStarted(count);
		
		if (count == 0) {
			notifyTestRunEnded(0);
			return;
		}
		
		long startTime= System.currentTimeMillis();
		if (fDebugMode)
			System.out.print("start send tree..."); //$NON-NLS-1$
		for (int i= 0; i < suites.length; i++) {
			sendTree(suites[i]);
		}
		if (fDebugMode)
			System.out.println("done send tree - time(ms): "+(System.currentTimeMillis()-startTime)); //$NON-NLS-1$

		long testStartTime= System.currentTimeMillis();
		for (int i= 0; i < suites.length; i++) {
			suites[i].run(fTestResult);
		}
		// inform ITestRunListeners of test end
		if (fTestResult == null || fTestResult.shouldStop())
			notifyTestRunStopped(System.currentTimeMillis() - testStartTime);
		else
			notifyTestRunEnded(System.currentTimeMillis() - testStartTime);
	}
	
	private int countTests(Test[] tests) {
		int count= 0;
		for (int i= 0; i < tests.length; i++) {
			if (tests[i] != null)
				count= count + tests[i].countTestCases();
		}
		return count;
	}
	
	/**
	 * Reruns a test as defined by the fully qualified class name and
	 * the name of the test.
	 */
	public void rerunTest(String className, String testName) {
		Test reloadedTest= null;
		try {
			Class reloadedTestClass= getClassLoader().loadClass(className);
			Class[] classArgs= { String.class };
			Constructor constructor= reloadedTestClass.getConstructor(classArgs);
			Object[] args= new Object[]{testName};
			reloadedTest=(Test)constructor.newInstance(args);
		} catch(Exception e) {
			runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.load", reloadedTest )); //$NON-NLS-1$
			return;
		}
		TestResult result= new TestResult();
		reloadedTest.run(result);
		notifyTestReran(result, className, testName);
	}


	/*
	 * @see TestListener#addError(Test, Throwable)
	 */
	public final void addError(Test test, Throwable throwable) {
		notifyTestFailed(MessageIds.TEST_ERROR, test.toString(), getTrace(throwable));
	}

	/*
	 * @see TestListener#addFailure(Test, AssertionFailedError)
	 */
	public final void addFailure(Test test, AssertionFailedError assertionFailedError) {
		notifyTestFailed(MessageIds.TEST_FAILED, test.toString(), getTrace(assertionFailedError));
	}

	/*
	 * @see TestListener#endTest(Test)
	 */
	public void endTest(Test test) {
		notifyTestEnded(test.toString());
	}

	/*
	 * @see TestListener#startTest(Test)
	 */
	public void startTest(Test test) {
		notifyTestStarted(test.toString());
	}
	
	private void sendTree(Test test){
		if(test instanceof TestDecorator){
			TestDecorator decorator= (TestDecorator) test;
			sendTree(decorator.getTest());		
		}
		else if(test instanceof TestSuite){
			TestSuite suite= (TestSuite) test;
			notifyTestTreeEntry(suite.toString().trim() + ',' + true + ',' + suite.testCount());
			for(int i=0; i < suite.testCount(); i++){	
				sendTree(suite.testAt(i));		
			}				
		}
		else {
			notifyTestTreeEntry(test.toString().trim() + ',' + false + ',' +  test.countTestCases());
		}
	}
	
	/**
	 * Returns the stack trace for the given throwable.
	 */
	private String getTrace(Throwable t) { 
		StringWriter stringWriter= new StringWriter();
		PrintWriter writer= new PrintWriter(stringWriter);
		t.printStackTrace(writer);
		StringBuffer buffer= stringWriter.getBuffer();
		return buffer.toString();
	}	

	/**
	 * Stop the current test run.
	 */
	protected void stop() {
		if (fTestResult != null) {
			fTestResult.stop();
		}
	}
	
	/**
	 * Connect to the remote test listener.
	 */
	private boolean connect() {
		if (fDebugMode)
			System.out.println("RemoteTestRunner: trying to connect" + fHost + ":" + fPort); //$NON-NLS-1$ //$NON-NLS-2$
		Exception exception= null;
		for (int i= 1; i < 10; i++) {
			try{
				fClientSocket= new Socket(fHost, fPort);
				fWriter= new PrintWriter(fClientSocket.getOutputStream(), false/*true*/);
				fReader= new BufferedReader(new InputStreamReader(fClientSocket.getInputStream()));
				new ReaderThread().start();
				return true;
			} catch(IOException e){
				exception= e;
			}
			try {
				Thread.sleep(2000);
			} catch(InterruptedException e) {
			}
		}
		runFailed(JUnitMessages.getFormattedString("RemoteTestRunner.error.connect", new String[]{fHost, Integer.toString(fPort)} )); //$NON-NLS-1$
		exception.printStackTrace();
		return false;
	}

	/**
	 * Shutsdown the connection to the remote test listener.
	 */
	private void shutDown() {
		if (fWriter != null) {
			fWriter.close();
			fWriter= null;
		}
		
		try {
			if (fReader != null) {
				fReader.close();
				fReader= null;
			}
		} catch(IOException e) {
			if (fDebugMode)
				e.printStackTrace();
		}
		
		try {
			if (fClientSocket != null) {
				fClientSocket.close();
				fClientSocket= null;
			}
		} catch(IOException e) {
			if (fDebugMode)	
				e.printStackTrace();
		}
	}


	private void sendMessage(String msg) {
		if(fWriter == null) 
			return;
		fWriter.println(msg);
	}


	private void notifyTestRunStarted(int testCount) {
		sendMessage(MessageIds.TEST_RUN_START + testCount);
	}


	private void notifyTestRunEnded(long elapsedTime) {
		sendMessage(MessageIds.TEST_RUN_END + elapsedTime);
		fWriter.flush();
		//shutDown();
	}


	private void notifyTestRunStopped(long elapsedTime) {
		sendMessage(MessageIds.TEST_STOPPED + elapsedTime );
		fWriter.flush();
		//shutDown();
	}

	private void notifyTestStarted(String testName) {
		sendMessage(MessageIds.TEST_START + testName);
		fWriter.flush();
	}

	private void notifyTestEnded(String testName) {
		sendMessage(MessageIds.TEST_END + testName);
	}

	private void notifyTestFailed(String status, String testName, String trace) {
		sendMessage(status + testName);
		sendMessage(MessageIds.TRACE_START);
		sendMessage(trace);
		sendMessage(MessageIds.TRACE_END);
		fWriter.flush();
	}

	private void notifyTestTreeEntry(String treeEntry) {
		sendMessage(MessageIds.TEST_TREE + treeEntry);
	}
	
	private void notifyTestReran(TestResult result, String testClass, String testName) {
		TestFailure failure= null;
		if (result.errorCount() > 0) {
			failure= (TestFailure)result.errors().nextElement();
		}
		if (result.failureCount() > 0) {
			failure= (TestFailure)result.failures().nextElement();
		}
		if (failure != null) {
			Throwable t= failure.thrownException();
			String trace= getTrace(t);
			sendMessage(MessageIds.RTRACE_START);
			sendMessage(trace);
			sendMessage(MessageIds.RTRACE_END);
			fWriter.flush();
		}
		String status= "OK"; //$NON-NLS-1$
		if (result.errorCount() > 0)
			status= "ERROR"; //$NON-NLS-1$
		else if (result.failureCount() > 0)
			status= "FAILURE"; //$NON-NLS-1$
		if (fPort != -1) {
			sendMessage(MessageIds.TEST_RERAN + testClass+" "+testName+" "+status); //$NON-NLS-1$ //$NON-NLS-2$
			fWriter.flush();
		}
	}
}	
