/**
 *  VUCAKO Bench in Java: main program.
 *   @author  PE
 *   @version 0.008 (2001/07/22)
 *   @since   0.006
 */
public class Bench {

    /** Maximum ordinal number of implemented test. */
    protected final static int MAX_TEST_NUMBER = 15;

    /** Default test number. */
    protected final static int DEFAULT_TEST_NUMBER = 1;

    /**
     *  Formats integer in &quot;%.3f&quot; C-format.
     *   @param  value Number to be formatted.
     *   @return String representation of the given number.
     */
    protected static String formatSec ( long value ) {
        return( Long.toString(value/1000L) + "." +
                Long.toString((value/100L)%10L) +
                Long.toString((value/10L)%10L) +
                Long.toString(value%10L) );
    }

    /**
     *  Runs the given benchmark.
     *   @param  b Initialized <code>Benchamrk</code> instance.
     *   @return Runing time in millicesonds.
     */
    protected static long runTest ( Benchmark b ) {
        long elapsed = b.runTest();
        System.out.println( b.testResult() + ", elapsed time: " + formatSec(elapsed) + " sec" );
        return elapsed;
    }

    /**
     *  Main jBench routine.
     *   @param  args Arguments passed to the program.
     */
    public static void main ( String[] args ) {

        System.out.println("VUCAKO jBench ver 1.008c (c) 2001 Josef.Pelikan@mff.cuni.cz (OpenSource)");

        int testNo = DEFAULT_TEST_NUMBER;
        int argIndex;
        boolean alt = false;
        int clock = 100;                    // default clock spped in MHz
        String cpu = "unknown";             // default CPU description

        for ( argIndex = 0; argIndex < args.length; argIndex++ ) {
            if ( args[argIndex].equals("-alt") ) // alternative
                alt = true;
            else
            if ( args[argIndex].equals("-c") ) { // clock speed, CPU description
                if ( argIndex+1 < args.length ) {
                    clock = Integer.parseInt(args[++argIndex]);
                    if ( argIndex+1 < args.length )
                        cpu = args[++argIndex];
                    }
                }
            else
            if ( args[argIndex].equals("-t") ) { // self-test
                RandomJames rnd = new RandomJames();
                System.out.println( "RandomJames pseudo-random generator test: " +
                                    (rnd.test() ? "passed" : "failed") );
                return;
                }
            else {                          // test #
                testNo = Integer.parseInt(args[argIndex]);
                if ( testNo < 1 ) testNo = 1;
                else
                if ( testNo > MAX_TEST_NUMBER ) testNo = MAX_TEST_NUMBER;
                }
            }
        System.out.println( "Test #" + Integer.toString(testNo) +
                            (alt ? "(alt)" : "") + " on \"" + cpu + "\" (" + clock + "MHz):" );

        long elapsed = 0L;                  // test running time in milliseconds
        switch ( testNo ) {

            case  1:                        // Eratosthen
                elapsed = runTest( alt ? new BenchmarkEratosthenAlt() : new BenchmarkEratosthen() );
                break;

            case  2:                        // Image transposition (16MB image)
            case  3:                        // Image transposition (64MB image)
                elapsed = runTest( new BenchmarkTranspose(testNo,alt) );
                break;

            case  4:                        // Arbitrage sequence lookup
                elapsed = runTest( new BenchmarkArbitrage() );
                break;

            case  5:                        // Needle-throwing simulation
                elapsed = runTest( new BenchmarkNeedle() );
                break;

            case  6:                        // Fast memory-copy
                elapsed = runTest( new BenchmarkMemoryCopy() );
                break;

            case  7:                        // Monte-Carlo form-factor
                elapsed = runTest( new BenchmarkFormFactor() );
                break;

            case  8:                        // Merge-sort on disk
                elapsed = runTest( alt ? new BenchmarkMergeSortAlt() : new BenchmarkMergeSort() );
                break;

            case  9:                        // Wavelet transform in memory
                elapsed = runTest( new BenchmarkWaveletMemory() );
                break;

            case 10:                        // Wavelet transform on disk
                elapsed = runTest( new BenchmarkWaveletDisk() );
                break;

            case 11:                        // Adaptive K-D tree on disk
                elapsed = runTest( new BenchmarkAKDTree() );
                break;

            case 12:                        // Quick-sort in virtual memory (64MB array)
            case 13:                        // Quick-sort in virtual memory (256MB array)
            case 14:                        // Quick-sort in virtual memory (1GB array)
                elapsed = runTest( new BenchmarkQuickSort(testNo) );
                break;

            case 15:                        // Garbage collection in 64MB RAM
                elapsed = runTest( new BenchmarkGC() );
                break;

            }

            // result processing ["clock","cpu","elapsed"]:
        boolean changed = false;
        if ( elapsed > 0L ) {
            BenchResults res = new BenchResults(null);
            changed = res.addResult(testNo,clock,cpu,elapsed);
            res.close();
            }

        try {
            Thread.sleep( changed ? 12000L : 8000L );
            }
        catch ( InterruptedException e ) {}
    }

}
