/**
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright
 *    statements and notices.  Redistributions must also contain a
 *    copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. The name "Exolab" must not be used to endorse or promote
 *    products derived from this Software without prior written
 *    permission of Intalio, Inc.  For written permission,
 *    please contact info@exolab.org.
 *
 * 4. Products derived from this Software may not be called "Exolab"
 *    nor may "Exolab" appear in their names without prior written
 *    permission of Intalio, Inc. Exolab is a registered
 *    trademark of Intalio, Inc.
 *
 * 5. Due credit should be given to the Exolab Project
 *    (http://www.exolab.org/).
 *
 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright 2001-2003 (C) Intalio, Inc. All Rights Reserved.
 *
 * $Id: CastorTestSuiteRunner.java,v 1.3 2005/02/27 01:13:54 kvisco Exp $
 */

package org.exolab.castor.tests.framework;

import java.io.*;
import junit.framework.*;

/**
 * This class is used to start the test for the Castor Testing Framework.
 *
 * @author <a href="mailto:gignoux@kernelcenter.org">Sebastien Gignoux</a>
 * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
 * @version $Revision: 1.3 $ $Date: 2005/02/27 01:13:54 $
 */
public class CastorTestSuiteRunner extends TestCase {

    /**
     * The place where all the files generated by the different tests have to be
     * put.
     */
    public final static String TEST_OUTPUT_ROOT = "build/tests/output/";

    /**
     * Name of the system property where the root of the test case is stored.
     */
    private final static String TEST_ROOT_PROPERTY = "org.exolab.castor.tests.TestRoot";

    /**
     * Root of the test cases. We start to lookup for test cases in this
     * directory. We are forced to communicate with suite() by this way. A static
     * field could not work as junit has its own defining class loader.
     */
    private static String TEST_ROOT;

    /**
     * File separator for this system.
     */
    private final static String FILE_SEPARATOR = System.getProperty("file.separator");

    /**
     * Command line argument that causes the help/options
     * to be displayed
     */
    private final static String HELP_ARG = "-help";
    
    /**
     * Command line argument to set the verbose mode
     */
    private final static String VERBOSE_ARG = "-verbose";

    /**
     * Command line argument to set the text mode (no GUI)
     */
    private final static String TEXT_MODE_ARG = "-text";

    /**
     * Command line argument to print or not the stack trace
     */
    private final static String PRINT_STACK = "-printStack";

    /**
     * Command line argument to specify the seed for the pseudo-random number generator
     */
    private final static String SEED_ARG = "-seed";


    /**
     * Default constructor that takes a name
     * per test case
     */
    public CastorTestSuiteRunner(String name) {
        super(name);
    }


    /**
     * Starts a TestCaseAggregator to collect all the tests in the root directory
     * and its subdirectories.
     *
     * @return A non-null test suite.
     */
    public static Test suite() {

        TEST_ROOT = System.getProperty(TEST_ROOT_PROPERTY);

        //-- cleanup for relative directories "." and ".."
        if (TEST_ROOT.equals(".") || TEST_ROOT.equals("..")) {
            File tmp = new File(TEST_ROOT);
            try {
                TEST_ROOT = tmp.getCanonicalPath();
            } catch(java.io.IOException iox) {
                iox.printStackTrace();
                System.exit(1);
            }
        }

        //-- some clean up needed because URLClassLoader can't handle a
        //-- file URL that starts with "./"
        else if ( (TEST_ROOT.startsWith("./")) || (TEST_ROOT.startsWith(".\\")) ) {
            TEST_ROOT = TEST_ROOT.substring(2);
        }

        File testRoot = new File(TEST_ROOT);

        if (!testRoot.exists()) {
            System.out.println("\nUnable to locate the root directory for the test cases");
            System.exit(1);
        }
        return new TestCaseAggregator(testRoot, TEST_OUTPUT_ROOT).suite();
    }


    /**
     * Runs the Castor Test.
     */
    public static void main(String args[]) {
      
        if (args.length == 0)
            error();
        boolean text = false; // GUI by default

        for (int i=0; i<args.length; ++i) {
            
            System.out.println("arg: '" + args[i] +"'");

            if (args[i].equals(VERBOSE_ARG)) {
                // Set up verbose mode
                System.out.println("Verbose on");
                System.setProperty(TestCaseAggregator.VERBOSE_PROPERTY, "true");
            } else if (args[i].equals(PRINT_STACK)) {
                System.out.println("Printing stack traces on.");
                System.setProperty(TestCaseAggregator.PRINT_STACK_TRACE, "true");

            } else if (args[i].equals(TEXT_MODE_ARG)) {
                System.out.println("Running in text mode.");
                text = true;
            } else if (args[i].equals(SEED_ARG)) {
                // The next argument should be a number...
                try {
                     long seed = new Long(args[++i]).longValue();
                     RandomHelper.setSeed(seed);
                } catch (NumberFormatException nfe) {
                    System.out.println("Unable to parse the number for the seed");
                    error();
                }
            } 
            else if (args[i].equals(HELP_ARG)) {
                usage();
                return;
            }
            else if (System.getProperty(TEST_ROOT_PROPERTY) == null) {
                System.setProperty(TEST_ROOT_PROPERTY, args[i]);
            }
            else {
                error();
            }
        }

        if (System.getProperty(TEST_ROOT_PROPERTY) == null)
            error();

        System.out.println("Using '" + RandomHelper.getSeed() + "' as seed for the initialization of the pseudo-random number generator");

        String[] testCaseName = {CastorTestSuiteRunner.class.getName()};

        if (text)
            junit.textui.TestRunner.main(testCaseName);
        else
            junit.swingui.TestRunner.main(testCaseName);
    }

    /**
     * Print usage and exit.
     */
    private static void error() {
        usage();
        System.exit(1);
    }
    
    /**
     * Print usage
     */
    private static void usage() {
        System.out.println("Castor Testing Framework ");
        System.out.println("------------------------ ");
        System.out.println("argument: [" + VERBOSE_ARG + "] [" + TEXT_MODE_ARG + "] [" + PRINT_STACK + "] [" + SEED_ARG + " <seed value>] <root test directory or a castor jar test file>");
        System.out.println("   " + HELP_ARG + " : displays this screen.");
        System.out.println("   " + VERBOSE_ARG + " : give detailed execution information for the each test");
        System.out.println("   " + TEXT_MODE_ARG + " : run the test without starting the swing gui");
        System.out.println("   " + PRINT_STACK + " : Print the full stack trace on the console when an exception is thrown");
        System.out.println("   " + SEED_ARG  + " <seed value> : force the use of a given seed for the pseudo-random number generator used for the random tests");
    }
    
}
