package junit.runner;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.NumberFormat;
import java.util.Properties;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestListener;
import junit.framework.TestSuite;

/**
 * Base class for all test runners.
 * This class was born live on stage in Sardinia during XP2000.
 */
public abstract class BaseTestRunner implements TestListener {
	public static final String SUITE_METHODNAME= "suite";

	private static Properties fPreferences;
	static int fgMaxMessageLength= 500;
	static boolean fgFilterStack= true;
	boolean fLoading= true;

    /*
    * Implementation of TestListener
    */
	public synchronized void startTest(Test test) {
		testStarted(test.toString());
	}

	protected static void setPreferences(Properties preferences) {
		fPreferences= preferences;
	}

	protected static Properties getPreferences() {
		if (fPreferences == null) {
			fPreferences= new Properties();
	 		fPreferences.put("loading", "true");
 			fPreferences.put("filterstack", "true");
  			readPreferences();
		}
		return fPreferences;
	}

	public static void savePreferences() throws IOException {
		FileOutputStream fos= new FileOutputStream(getPreferencesFile());
		try {
			getPreferences().store(fos, "");
		} finally {
			fos.close();
		}
	}

	public static void setPreference(String key, String value) {
		getPreferences().put(key, value);
	}

	public synchronized void endTest(Test test) {
		testEnded(test.toString());
	}

	public synchronized void addError(final Test test, final Throwable t) {
		testFailed(TestRunListener.STATUS_ERROR, test, t);
	}

	public synchronized void addFailure(final Test test, final AssertionFailedError t) {
		testFailed(TestRunListener.STATUS_FAILURE, test, t);
	}

	// TestRunListener implementation

	public abstract void testStarted(String testName);

	public abstract void testEnded(String testName);

	public abstract void testFailed(int status, Test test, Throwable t);

	/**
	 * Returns the Test corresponding to the given suite. This is
	 * a template method, subclasses override runFailed(), clearStatus().
	 */
	public Test getTest(String suiteClassName) {
		if (suiteClassName.length() <= 0) {
			clearStatus();
			return null;
		}
		Class<?> testClass= null;
		try {
			testClass= loadSuiteClass(suiteClassName);
		} catch (ClassNotFoundException e) {
			String clazz= e.getMessage();
			if (clazz == null)
				clazz= suiteClassName;
			runFailed("Class not found \""+clazz+"\"");
			return null;
		} catch(Exception e) {
			runFailed("Error: "+e.toString());
			return null;
		}
		Method suiteMethod= null;
		try {
			suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
	 	} catch(Exception e) {
	 		// try to extract a test suite automatically
			clearStatus();
			return new TestSuite(testClass);
		}
		if (! Modifier.isStatic(suiteMethod.getModifiers())) {
			runFailed("Suite() method must be static");
			return null;
		}
		Test test= null;
		try {
			test= (Test)suiteMethod.invoke(null, (Object[])new Class[0]); // static method
			if (test == null)
				return test;
		}
		catch (InvocationTargetException e) {
			runFailed("Failed to invoke suite():" + e.getTargetException().toString());
			return null;
		}
		catch (IllegalAccessException e) {
			runFailed("Failed to invoke suite():" + e.toString());
			return null;
		}

		clearStatus();
		return test;
	}

	/**
	 * Returns the formatted string of the elapsed time.
	 */
	public String elapsedTimeAsString(long runTime) {
		return NumberFormat.getInstance().format((double)runTime/1000);
	}

	/**
	 * Processes the command line arguments and
	 * returns the name of the suite class to run or null
	 */
	protected String processArguments(String[] args) {
		String suiteName= null;
		for (int i= 0; i < args.length; i++) {
			if (args[i].equals("-noloading")) {
				setLoading(false);
			} else if (args[i].equals("-nofilterstack")) {
				fgFilterStack= false;
			} else if (args[i].equals("-c")) {
				if (args.length > i+1)
					suiteName= extractClassName(args[i+1]);
				else
					System.out.println("Missing Test class name");
				i++;
			} else {
				suiteName= args[i];
			}
		}
		return suiteName;
	}

	/**
	 * Sets the loading behaviour of the test runner
	 */
	public void setLoading(boolean enable) {
		fLoading= enable;
	}
	/**
	 * Extract the class name from a String in VA/Java style
	 */
	public String extractClassName(String className) {
		if(className.startsWith("Default package for"))
			return className.substring(className.lastIndexOf(".")+1);
		return className;
	}

	/**
	 * Truncates a String to the maximum length.
	 */
	public static String truncate(String s) {
		if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength)
			s= s.substring(0, fgMaxMessageLength)+"...";
		return s;
	}

	/**
	 * Override to define how to handle a failed loading of
	 * a test suite.
	 */
	protected abstract void runFailed(String message);

	/**
	 * Returns the loaded Class for a suite name.
	 */
	protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
		return Class.forName(suiteClassName);
	}

	/**
	 * Clears the status message.
	 */
	protected void clearStatus() { // Belongs in the GUI TestRunner class
	}

	protected boolean useReloadingTestSuiteLoader() {
		return getPreference("loading").equals("true") && fLoading;
	}

	private static File getPreferencesFile() {
	 	String home= System.getProperty("user.home");
 		return new File(home, "junit.properties");
 	}

 	private static void readPreferences() {
 		InputStream is= null;
 		try {
 			is= new FileInputStream(getPreferencesFile());
 			setPreferences(new Properties(getPreferences()));
			getPreferences().load(is);
		} catch (IOException e) {
			try {
				if (is != null)
					is.close();
			} catch (IOException e1) {
			}
		}
 	}

 	public static String getPreference(String key) {
 		return getPreferences().getProperty(key);
 	}

 	public static int getPreference(String key, int dflt) {
 		String value= getPreference(key);
 		int intValue= dflt;
 		if (value == null)
 			return intValue;
 		try {
 			intValue= Integer.parseInt(value);
 	 	} catch (NumberFormatException ne) {
 		}
 		return intValue;
 	}

	/**
	 * Returns a filtered stack trace
	 */
	public static String getFilteredTrace(Throwable t) {
		StringWriter stringWriter= new StringWriter();
		PrintWriter writer= new PrintWriter(stringWriter);
		t.printStackTrace(writer);
		StringBuffer buffer= stringWriter.getBuffer();
		String trace= buffer.toString();
		return BaseTestRunner.getFilteredTrace(trace);
	}

	/**
	 * Filters stack frames from internal JUnit classes
	 */
	public static String getFilteredTrace(String stack) {
		if (showStackRaw())
			return stack;

		StringWriter sw= new StringWriter();
		PrintWriter pw= new PrintWriter(sw);
		StringReader sr= new StringReader(stack);
		BufferedReader br= new BufferedReader(sr);

		String line;
		try {
			while ((line= br.readLine()) != null) {
				if (!filterLine(line))
					pw.println(line);
			}
		} catch (Exception IOException) {
			return stack; // return the stack unfiltered
		}
		return sw.toString();
	}

	protected static boolean showStackRaw() {
		return !getPreference("filterstack").equals("true") || fgFilterStack == false;
	}

	static boolean filterLine(String line) {
		String[] patterns= new String[] {
			"junit.framework.TestCase",
			"junit.framework.TestResult",
			"junit.framework.TestSuite",
			"junit.framework.Assert.", // don't filter AssertionFailure
			"junit.swingui.TestRunner",
			"junit.awtui.TestRunner",
			"junit.textui.TestRunner",
			"java.lang.reflect.Method.invoke("
		};
		for (int i= 0; i < patterns.length; i++) {
			if (line.indexOf(patterns[i]) > 0)
				return true;
		}
		return false;
	}

 	static {
 		fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
 	}

}
