/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

package javax.jdo.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.io.PrintStream;

import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import junit.textui.ResultPrinter;
import junit.textui.TestRunner;

/**
 * TestRunner class for running a single test or a test suite in batch
 * mode. The format of the test output is specified by the result printer
 * class. The main method sets an exit code according to the test result:
 * <ul>
 * <li><code>0</code>: success
 * <li><code>1</code>: failure, the test shows an unexpected behavior
 * <li><code>2</code>: exception, the test throws an unhandled excption 
 * </ul>
 * 
 * @author Michael Bouschen
 */
public class BatchTestRunner
    extends TestRunner
{
    /** Name of the system property to specify the result printer class. */
    public static final String RESULTPRINTER_PROPERTY = "ResultPrinterClass"; 
    
    /** Default of the system property ResultPrinterClass. */
    public static final String RESULTPRINTER_DEFAULT = BatchResultPrinter.class.getName();
    
    /** 
     * Constructor. 
     * It creates a result printer instance based on the system property
     * and delegates to the constructor taking a result printer argument. 
     */
    public BatchTestRunner() {
    	super();
        setPrinter(getResultPrinter());
    }
    
    /**  
     * Constructor. USes teh specified resultPrinter to format the test result.
     */
    public BatchTestRunner(ResultPrinter resultPrinter) {
        super(resultPrinter);
    }

    /** Runs all test methods from the specified class. */
    public static void run(Class clazz) {
        run(new TestSuite(clazz));
    }
    
    /** Runs the specified test. */
    public static TestResult run(Test test) {
		return new BatchTestRunner().doRun(test);
    }

	/**	Runs the specified test and waits until the user types RETURN. */
	public static void runAndWait(Test suite) {
		new BatchTestRunner().doRun(suite, true);
	}

	/** 
     * Runs in batch mode and sets an exit code. If the specified String
     * array includes a single fully qualified class name, this test class
     * is executed. If it is empty it runs the TestListSuite.
     */
    public static void main(String args[]) {
		BatchTestRunner aTestRunner= new BatchTestRunner();
		try {
            /*
            if ((args == null) || args.length == 0)
                args = new String[] { TestListSuite.class.getName() };
            */
			TestResult r = aTestRunner.start(args);
			if (!r.wasSuccessful()) 
				System.exit(FAILURE_EXIT);
			System.exit(SUCCESS_EXIT);
		} catch(Exception e) {
			System.err.println(e.getMessage());
			System.exit(EXCEPTION_EXIT);
		}
	}
    
    /** Returns a result printer instance. n instance of tCheck the system property */
    protected ResultPrinter getResultPrinter() {
      	String className =  System.getProperty(RESULTPRINTER_PROPERTY);
        if (className != null) {
            className = className.trim();
            if (className.length() != 0) {
                String msg = null;
                try {
                    // get class instance
                    Class clazz = Class.forName(className);
                    // constructor taking PrintStream arg
                    Constructor ctor = clazz.getConstructor(
                        new Class[] { PrintStream.class } );
                    // create instance
                    return (ResultPrinter)ctor.newInstance(
                        new Object[] { System.out });
                }
                catch (ClassNotFoundException ex) {
                    // specified ResultPrinter class not 
                    msg = "Cannot find specified result printer class " + 
                        className + ".";
                }
                catch (NoSuchMethodException ex) {
                    msg = "Class " + className + 
                        " does not provide constructor taking a PrintStream.";
                }
                catch (InstantiationException ex) {
                    msg = "Class " + className + " is abstract.";
                }
                catch (IllegalAccessException ex) {
                    msg = "Constructor taking a PrintStream of class " + 
                        className + " is not accessible.";
                }
                catch (InvocationTargetException ex) {
                    msg = "Constructor call results in exception " + ex + ".";
                }

                // ResultPrinter class specified, but not avaiable
                System.out.println(msg);
                ResultPrinter printer = getDefaultResultPrinter();
                System.out.println("Using default result printer of class " + 
                                   printer.getClass().getName());
            }
        }
        
        // ResultPrinter class not specified => use default
        return getDefaultResultPrinter();
    }

    /** 
     * Returns an instance of the default result printer class
     * BatchResultPrinter.
     */
    protected ResultPrinter getDefaultResultPrinter() {
        return new BatchResultPrinter(System.out);
    }
    

}

