/*
 * 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 org.apache.jdo.tck.util;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

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

import javax.jdo.JDOFatalException;

import org.apache.jdo.tck.JDO_Test;

/**
 * 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();

    /** */
    public static final String LOG_DIRECTORY;

    static {
        String directory = System.getProperty("jdo.tck.log.directory");
        if (directory!=null &&
            !directory.endsWith(File.separator)) {
            directory += File.separator;
        }
        LOG_DIRECTORY = directory;
    }
    

    /** 
     * 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 the specified resultPrinter to format the test result.
     * @param resultPrinter the result printer
     */
    public BatchTestRunner(ResultPrinter resultPrinter) {
        super(resultPrinter);
    }

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

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

    /**
     * Runs the specified test or test suite and closes the pmf.
     * @param test test or test suite
     * @return the test result
     */
    public TestResult doRun(Test test) {
        TestResult result = null;
        try {
            result = doRun(test, false);
            JDO_Test.dumpSupportedOptions(LOG_DIRECTORY + "configuration");
        } finally {
            JDO_Test.closePMF();
        }
        return result;
    }

    /**
     * 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.
     * @param args command line arguments
     */
    public static void main(String args[]) {
        try {
            TestResult r = new BatchTestRunner().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);
        }
    }

    /**
     * Starts the test
     * @param args arguments
     * @return the test result
     */
    public TestResult start(String[] args) {
        Test suite = null;
        if ((args == null) || args.length == 0) {
            String conf = System.getProperty("jdo.tck.cfg");
            throw new JDOFatalException(
                "Missing JDO TCK test classes for configuration '" + conf + 
                "'. Please check the property 'jdo.tck.classes'.");
        }
        else if (args.length == 1) {
            suite = getTest(args[0]);
        }
        else {
            suite = getTestSuite(args);
        }
        return doRun(suite);
    }

    /**
     * Returns a JUnit TestSuite instance for the classes of the specified
     * list of class names.
     * @param classNames class names
     * @return the test suite
     */
    protected TestSuite getTestSuite(String[] classNames) {
        TestSuite testSuite = new TestSuite();
        for (int i = 0; i < classNames.length; i++) {
            String className = classNames[i];
            try {
                testSuite.addTestSuite(Class.forName(className));
            }
            catch (ClassNotFoundException ex) {
                System.out.println(
                    "Cannot find test class '" + className + "'.");
            }
        }
        return testSuite;
    }

    /**
     * Returns a result printer instance. The system property
     * ResultPrinterClass specifies the class of the returned instanec. The
     * class must extend junit.textui.ResultPrinter.
     * @return the result printer
     */
    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 ctor = null;
                    OutputStream stream = null;

                    // choose constructor taking ConsoleFileOutput arg
                    if (!Boolean.getBoolean("no.log.file")) {
                        try {
                            ctor = clazz.getConstructor(
                            new Class[] { ConsoleFileOutput.class } );
                            stream = new ConsoleFileOutput();
                        }
                        catch (NoSuchMethodException ex) {
                            ctor = null;
                        }
                    }
                    
                    // choose constructor taking PrintStream arg
                    if (ctor == null) {
                        ctor = clazz.getConstructor(
                                new Class[] { PrintStream.class } );
                        stream = System.out;
                    }
                        
                    return (ResultPrinter)ctor.newInstance(
                        new Object[] { stream });
                }
                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.
     * @return the default result printer
     */
    protected ResultPrinter getDefaultResultPrinter() {
        return new BatchResultPrinter(System.out);
    }
    
    /**
     * Returns a file name which is determined by method
     * {@link BatchTestRunner#changeFileName(String)}.
     * The file name has suffix <code>.txt</code>.
     * @return the file name
     */
    public static String getFileName() {
        return changeFileName("junit.txt");
    }
    
    /**
     * Returns a file name which is constructed by values
     * of some system properties appended by the given file name.
     * The system properties evaluated are:
     * <ul>
     * <li>jdo.tck.log.directory: Specifies the directory for the file.</li>
     * <li>jdo.tck.database, jdo.tck.cfg: 
     * The values of these properties prepend the given file name.</li>
     * <li>jdo.tck.identitytype: The value of this property is replaced by
     * <code>"app"</code> if it equals <code>"applicationidentity"</code>, 
     * else it is replaced by <code>"dsid"</code>.</li>
     * </ul>
     * The returned file name is constructed as follows:<br>
     * ${jdo.tck.log.directory}/${jdo.tck.database}-${jdo.tck.identitytype}-${jdo.tck.cfg}${given file name}
     * Values of properties which do not exist default to <code>""</code>. 
     * @param fileName the file name
     * @return the changed file name
     */
    public static String changeFileName(String fileName) {
        String directory = LOG_DIRECTORY;
        String db = System.getProperty("jdo.tck.database");
        
        String identityType = System.getProperty("jdo.tck.identitytype");
        if (identityType!=null) {
            if (identityType.equals("applicationidentity")) {
                identityType = "app";
            } else { 
                identityType = "dsid";
            }
        }
        
        String configuration = System.getProperty("jdo.tck.cfg");
        if (configuration!=null) {
            int index = configuration.indexOf('.');
            if (index!=-1) {
                configuration = configuration.substring(0, index);
            }
        }
        
        directory = fixPartialFileName(directory);
        db = fixPartialFileName(db, '-',
                new String[]{identityType, configuration, fileName});
        identityType = fixPartialFileName(identityType, '-',
                new String[]{configuration, fileName});
        configuration = fixPartialFileName(configuration, '-',
                new String[]{fileName});

        return directory + db + identityType + configuration + fileName;
    }
    
    private static String fixPartialFileName(String str) {
        if (str==null) {
            str = "";
        }
        return str;
    }
    
    private static String fixPartialFileName(String str, char c, 
            String[] values) {
        str = fixPartialFileName(str);
        if (!str.equals("")) {
            for (int i = 0; i < values.length; i++) {
                String value = values[i];
                if (value!=null &&
                    !value.equals("") &&
                    !value.startsWith(".")) {
                    str += c;
                    break;
                }
            }
        }
        return str;
    }
}
