/*
**********************************************************************
* Copyright (c) 2002-2003, International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/perf/PerfTest.java,v $ 
**********************************************************************
*/
package com.ibm.icu.dev.test.perf;
import com.ibm.icu.dev.tool.UOption;
import com.ibm.icu.impl.LocaleUtility;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;
import java.util.Iterator;
import java.util.TreeSet;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.*;

/**
 * Base class for performance testing framework.  To use, subclass and
 * define one or more instance methods with names beginning with
 * "test" (case ignored).  Each such method must then call two
 * functions, setTestFunction(), and setEventsPerCall().  In addition,
 * the subclass should define a main() method that calls run() as
 * defined here.  If the subclasses uses any command line arguments
 * (beyond those handled automatically by this calss) then it should
 * override setup() to handle its arguments.
 * 
 * Example invocation:
 * java -cp classes -verbose:gc com.ibm.icu.dev.test.perf.UnicodeSetPerf --gc --passes 4 --iterations 100 UnicodeSetAdd [[:l:][:c:]]
 * 
 * Example output:
 * [GC 511K->192K(1984K), 0.0086170 secs]
 * [GC 704K->353K(1984K), 0.0059619 secs]
 * [Full GC 618K->371K(1984K), 0.0242779 secs]
 * [Full GC 371K->371K(1984K), 0.0228649 secs]
 * = testUnicodeSetAdd begin 100
 * = testUnicodeSetAdd end 11977 1109044
 * = testUnicodeSetAdd begin 100
 * = testUnicodeSetAdd end 12047 1109044
 * = testUnicodeSetAdd begin 100
 * = testUnicodeSetAdd end 11987 1109044
 * = testUnicodeSetAdd begin 100
 * = testUnicodeSetAdd end 11978 1109044
 *
 * The [] lines are emitted by the JVM as a result of the -verbose:gc
 * switch.
 *
 * Lines beginning with '=' are emitted by PerfTest:
 *
 * = testUnicodeSetAdd begin 100
 * A 'begin' statement contains the name of the setup method, which
 * determines what test function is measures, and the number of
 * iterations that will be times.
 *
 * = testUnicodeSetAdd end 12047 1109044
 * An 'end' statement gives the name of the setup method again, and
 * then two integers.  The first is the total elapsed time in
 * milliseconds, and the second is the number of events per iteration.
 * In this example, the time per event is 12047 / (100 * 1109044) or
 * 108.6 ns/event.
 *
 * Raw times are given as integer ms, because this is what the system
 * measures.
 *
 * @author Alan Liu
 * @since ICU 2.4
 */
public abstract class PerfTest {

    /**
     * A map of munged names to Method objects.  All available methods
     * in the current object beginning with "test" (case ignored).
     */
    private Map availableTests; // NOT static

    // Command-line options set these:
    protected boolean        verbose;
    protected String         sourceDir;
    protected String         fileName;
    //protected String         resolvedFileName;
    protected String         encoding;
    protected boolean        uselen;
    protected int            iterations;
    protected int            passes;
    protected int            time;
    protected boolean        line_mode;
    protected boolean        bulk_mode;
    protected Locale         locale;
    protected boolean        doPriorGC;

    /**
     * Subclasses of PerfTest will need to create subclasses of
     * Function that define a call() method which contains the code to
     * be timed.  They then call setTestFunction() in their "Test..."
     * method to establish this as the current test functor.
     */
    public abstract static class Function {

        /**
         * Subclasses must implement this method to do the action to be
         * measured.
         */
        public abstract void call();

        /**
         * Subclasses may implement this method to return positive
         * integer indicating the number of operations in a single
         * call to this object's call() method.  If subclasses do not
         * override this method, the default implementation returns 1.
         */
        public long getOperationsPerIteration() {
            return 1;
        }

        /**
         * Subclasses may implement this method to return either positive
         * or negative integer indicating the number of events in a single
         * call to this object's call() method.  If subclasses do not
         * override this method, the default implementation returns -1,
         * indicating that events are not applicable to this test.
         * e.g: Number of breaks / iterations for break iterator
         */
        public long getEventsPerIteration() {
            return -1;
        }

        /**
         * Call call() n times in a tight loop and return the elapsed
         * milliseconds.  If n is small and call() is fast the return
         * result may be zero.  Small return values have limited
         * meaningfulness, depending on the underlying VM and OS.
         */
        public final long time(long n) {
            long start, stop;
            start = System.currentTimeMillis();
            while (n-- > 0) {
                call();
            }
            stop = System.currentTimeMillis();
            return stop - start; // ms
        }
    }

    /**
     * Exception indicating a usage error.
     */
    public static class UsageException extends Exception {
        public UsageException(String message) {
            super(message);
        }

        public UsageException() {
            super();
        }
    }

    /**
     * Constructor.
     */
    protected PerfTest() {
    }

    /**
     * Framework method.  Default implementation does not parse any
     * extra arguments.  Subclasses may override this to parse extra
     * arguments.  Subclass implementations should NOT call the base
     * class implementation.
     */
    protected void setup(String[] args) {
        if (args.length > 0) {
            throw new RuntimeException("Extra arguments received");
        }
    }

    /**
     * These must be kept in sync with getOptions().
     */
    static final int HELP1 = 0;
    static final int HELP2 = 1;
    static final int VERBOSE = 2;
    static final int SOURCEDIR = 3;
    static final int ENCODING = 4;
    static final int USELEN = 5;
    static final int FILE_NAME = 6;
    static final int PASSES = 7;
    static final int ITERATIONS = 8;
    static final int TIME = 9;
    static final int LINE_MODE = 10;
    static final int BULK_MODE = 11;
    static final int LOCALE = 12;
    // Options above here are identical to those in C; keep in sync with C
    // Options below here are unique to Java; shift down as necessary
    static final int GARBAGE_COLLECT = 13;
    static final int LIST = 14;

    UOption[] getOptions() {
        return new UOption[] {
            UOption.HELP_H(),
            UOption.HELP_QUESTION_MARK(),
            UOption.VERBOSE(),
            UOption.SOURCEDIR(),
            UOption.ENCODING(),
            UOption.DEF( "uselen",        'u', UOption.NO_ARG),
            UOption.DEF( "file-name",     'f', UOption.REQUIRES_ARG),
            UOption.DEF( "passes",        'p', UOption.REQUIRES_ARG),
            UOption.DEF( "iterations",    'i', UOption.REQUIRES_ARG),                    
            UOption.DEF( "time",          't', UOption.REQUIRES_ARG),
            UOption.DEF( "line-mode",     'l', UOption.NO_ARG),
            UOption.DEF( "bulk-mode",     'b', UOption.NO_ARG),
            UOption.DEF( "locale",        'L', UOption.REQUIRES_ARG),

            // Options above here are identical to those in C; keep in sync
            // Options below here are unique to Java

            UOption.DEF( "gc",            'g', UOption.NO_ARG), 
            UOption.DEF( "list",     (char)-1, UOption.NO_ARG), 
        };
    }

    /**
     * Subclasses should call this method in their main().  run() will
     * in turn call setup() with any arguments it does not parse.
     * This method parses the command line and runs the tests given on
     * the command line, with the given parameters.  See the class
     * description for details.
     */
    protected final void run(String[] args) throws Exception {
        ArrayList methodList = new ArrayList();
        Method meth = null;

        availableTests = null;
        doPriorGC = false;
        encoding = "";
        uselen = false;
        fileName = null;
        sourceDir = null;
        //lines = null;
        line_mode = false;
        //buffer = null;
        //bufferLen = 0;
        verbose = false;
        bulk_mode = false;
        passes = iterations = time = 0;
        locale = null;

        UOption[] options = getOptions();
        int remainingArgc = UOption.parseArgs(args, options);
        
        if(args.length==0 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
            throw new UsageException();
        }

        if(options[VERBOSE].doesOccur) {
            verbose = true;
        }
        
        if(options[SOURCEDIR].doesOccur) {
            sourceDir = options[SOURCEDIR].value;
        }
        
        if(options[ENCODING].doesOccur) {
            encoding = options[ENCODING].value;
        }
        
        if(options[USELEN].doesOccur) {
            uselen = true;
        }
        
        if(options[FILE_NAME].doesOccur){
            fileName = options[FILE_NAME].value;
        }
        
        if (options[TIME].doesOccur && options[ITERATIONS].doesOccur) {
            throw new UsageException("Cannot specify both time and iterations");
        }

        if(options[PASSES].doesOccur) {
            passes = Integer.parseInt(options[PASSES].value);
        }
        
        if(options[ITERATIONS].doesOccur) {
            iterations = Integer.parseInt(options[ITERATIONS].value);
            time =0;
        }
        
        if(options[TIME].doesOccur) {
            time = Integer.parseInt(options[TIME].value);
            iterations = 0;
        }
        
        if (options[LINE_MODE].doesOccur && options[BULK_MODE].doesOccur) {
            throw new UsageException("Cannot specify both line mode and bulk mode");
        }

        if(options[LINE_MODE].doesOccur) {
            line_mode = true;
            bulk_mode = false;
        }
        
        if(options[BULK_MODE].doesOccur) {
            bulk_mode = true;
            line_mode = false;
        }
    
        if(options[LOCALE].doesOccur) {
            locale = LocaleUtility.getLocaleFromName(options[LOCALE].value);
        }

        if(options[GARBAGE_COLLECT].doesOccur) {
            doPriorGC = true;
        }

        int i, j;
        for (i=0; i<remainingArgc; ++i) {

            // is args[i] a method name?
            Method m = getTestMethod(args[i]);
            if (m != null) {
                methodList.add(m);
                continue;
            }

            // args[i] is neither a method name nor a number.  Pass
            // everything from here on through to the subclass via
            // setup().
            break;
        }

        if (methodList.size() < 1 || options[LIST].doesOccur) {
            System.err.println("Available tests:");
            Iterator methods = getAvailableTests().values().iterator();
            TreeSet methodNames = new TreeSet();
            while (methods.hasNext()) {
                methodNames.add(((Method)methods.next()).getName());
            }
            Iterator tests = methodNames.iterator();
            while (tests.hasNext()) {
                System.err.println(" " + tests.next());
            }
            if (options[LIST].doesOccur) {
                System.exit(0);
            }
            throw new UsageException("Must specify at least one method name");
        }

        // Pass remaining arguments, if any, through to the subclass
        // via setup() method.
        String[] subclassArgs = new String[remainingArgc - i];
        for (j=0; i<remainingArgc; ++j) {
            subclassArgs[j] = args[i++];
        }
        setup(subclassArgs);

        if (doPriorGC) {
            // Put the heap in a consistent state
            gc();
        }

        final Object[] NO_ARGS = new Object[0];

        // Run the tests
        for (i=0; i<methodList.size(); ++i) {
            meth = (Method) methodList.get(i);

            // Call meth to set up the test
           // long eventsPerCall = -1;
            Function testFunction = (Function)meth.invoke(this, NO_ARGS);
            if (testFunction == null) {
                throw new RuntimeException(meth.getName() + " failed to return a test function");
            }
            if (testFunction.getOperationsPerIteration() < 1) {
                throw new RuntimeException(meth.getName() + " returned an illegal operations/iteration()");
            }

            int n;
            long t;
            for (j=0; j<passes; ++j) {
                if (iterations > 0) {
                    // Run specified number of iterations
                    System.out.println("= " + meth.getName() + " begin " + iterations + " iterations");
                    t = testFunction.time(iterations);
                    System.out.println("= " + meth.getName() + " end " + (t/1000.0) + " " + testFunction.getOperationsPerIteration());
                } else {
                    // Run for specified duration in seconds
                    System.out.println("= " + meth.getName() + " begin " + time + " seconds");
                    n = time * 1000; // s => ms
                    //System.out.println("# " + meth.getName() + " " + n + " sec");                            
                    int loops = 0;
                    int failsafe = 1; // last resort for very fast methods
                    t = 0;
                    while (t < (int)(n * 0.9)) { // 90% is close enough
                        if (loops == 0 || t == 0) {
                            loops = failsafe;
                            failsafe *= 10;
                        } else {
                            //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);                            
                            loops = (int)((double)n / t * loops + 0.5);
                            if (loops == 0) {
                                throw new RuntimeException("Unable to converge on desired duration");
                            }
                        }
                        //System.out.println("# " + meth.getName() + " x " + loops);
                        t = testFunction.time(loops);
                    }
                    System.out.println("= " + meth.getName() + " end " + (t/1000.0) + " " + testFunction.getOperationsPerIteration() +
                                       " " + loops);
                }
            }
        }
    }

    /**
     * Invoke the runtime's garbage collection procedure repeatedly
     * until the amount of free memory stabilizes to within 10%.
     */
    protected void gc() {
        if (false) {
            long last;
            long free = 1;
            Runtime runtime = Runtime.getRuntime();
            do {
                runtime.gc();
                last = free;
                free = runtime.freeMemory();
            } while (((double)Math.abs(free - last)) / free > 0.1);
            // Wait for the change in free memory to drop under 10%
            // between successive calls.
        }

        // From "Java Platform Performance".  This is the procedure
        // recommended by Javasoft.
        try {
            System.gc();
            Thread.sleep(100);
            System.runFinalization();
            Thread.sleep(100);
            
            System.gc();
            Thread.sleep(100);
            System.runFinalization();
            Thread.sleep(100);
        } catch (InterruptedException e) {}
    }

    /**
     * Return a map of String to Method objects.  Each string is a
     * munged all-lowercase name.  For this reason, test methods
     * (beginning with "test", ignoring case) must not collide when
     * case folded.
     */
    private Map getAvailableTests() {
        if (availableTests == null) {
            availableTests = new HashMap();
            Method[] methods = getClass().getDeclaredMethods();
            for (int i=0; i<methods.length; i++) {
                String name = methods[i].getName().toLowerCase();
                // Note: methods named "test()" are ignored
                if (name.length() > 4 && name.startsWith("test")) {
                    if (availableTests.get(name) != null) {
                        throw new RuntimeException("Duplicate method name ignoring case: " + name);
                    }
                    availableTests.put(name, methods[i]);
                }
            }
        }
        return availableTests;
    }

    /**
     * Given a name, return the associated Method object, or null if
     * not found.  The given name will map to a method of the same
     * name, or a method named "test" + name.  Case is ignored.
     */
    private Method getTestMethod(String name) {
        Map avail = getAvailableTests();
        String key = name.toLowerCase();
        Method m = (Method) avail.get(key);
        if (m != null) {
            return m;
        }
        return (Method) avail.get("test" + key);
    }

    /**
     * Private utility to convert a List of Integer objects to int[].
     */
    private static int[] toIntArray(List list) {
        int[] result = new int[list.size()];
        for (int i=0; i<list.size(); ++i) {
            result[i] = ((Integer) list.get(i)).intValue();
        }
        return result;
    }
    public static char[] readToEOS(InputStreamReader stream) {
        ArrayList vec = new ArrayList();
        int count = 0;
        int pos = 0;
        final int MAXLENGTH = 0x8000; // max buffer size - 32K
        int length = 0x80; // start with small buffers and work up
        do {
            pos = 0;
            length = length >= MAXLENGTH ? MAXLENGTH : length * 2;
            char[] buffer = new char[length];
            try {
                do {
                    int n = stream.read(buffer, pos, length - pos);
                    if (n == -1) {
                    break;
                    }
                    pos += n;
                } while (pos < length);
            }
            catch (IOException e) {
            }
            vec.add(buffer);
            count += pos;
        } while (pos == length);
                            
        char[] data = new char[count];
        pos = 0;
        for (int i = 0; i < vec.size(); ++i) {
            char[] buf = (char[])vec.get(i);
            int len = Math.min(buf.length, count - pos);
            System.arraycopy(buf, 0, data, pos, len);
            pos += len;
        }
        return data;
    }
    public static byte[] readToEOS(InputStream stream) {

        ArrayList vec = new ArrayList();
        int count = 0;
        int pos = 0;
        final int MAXLENGTH = 0x8000; // max buffer size - 32K
        int length = 0x80; // start with small buffers and work up
        do {
            pos = 0;
            length = length >= MAXLENGTH ? MAXLENGTH : length * 2;
            byte[] buffer = new byte[length];
            try {
                do {
                    int n = stream.read(buffer, pos, length - pos);
                    if (n == -1) {
                    break;
                    }
                    pos += n;
                } while (pos < length);
            }
            catch (IOException e) {
            }
            vec.add(buffer);
            count += pos;
        } while (pos == length);
                            
                            
        byte[] data = new byte[count];
        pos = 0;
        for (int i = 0; i < vec.size(); ++i) {
            byte[] buf = (byte[])vec.get(i);
            int len = Math.min(buf.length, count - pos);
            System.arraycopy(buf, 0, data, pos, len);
            pos += len;
        }
        return data;
    }
    
    public String[] readLines(String fileName, String encoding, boolean bulkMode) {
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            fis = new FileInputStream(fileName);
            isr = new InputStreamReader(fis, encoding);
            br= new BufferedReader(isr);
        } catch (Exception e) {
            System.err.println("Error: File access exception: " + e.getMessage() + "!");
            System.exit(1);
        }
        ArrayList list = new ArrayList();
        while (true) {
            String line = null;
            try {
                line = readDataLine(br);
            } catch (Exception e) {
                System.err.println("Read File Error" + e.getMessage() + "!");
                System.exit(1);
            }
            if (line == null) break;
            if (line.length() == 0) continue;
            list.add(line);
        }
        
        int size = list.size();
        String[] lines = null;
        
        if (bulkMode) {
            lines = new String[1];
            StringBuffer buffer = new StringBuffer("");
            for (int i = 0; i < size; ++i) {
                buffer.append((String) list.get(i));
                /*if (i < (size - 1)) {
                    buffer.append("\r\n");
                }*/
            }
            lines[0] = buffer.toString();
        } else {
            lines = new String [size];
            for (int i = 0; i < size; ++i) {
                lines[i] = (String) list.get(i);
            }
        }
        
        return lines;
    }
    
    public String readDataLine(BufferedReader br) throws Exception {
        String originalLine = "";
        String line = "";
        try {
            line = originalLine = br.readLine();
            if (line == null) return null;
            if (line.length() > 0 && line.charAt(0) == 0xFEFF) line = line.substring(1);
            int commentPos = line.indexOf('#');
            if (commentPos >= 0) line = line.substring(0, commentPos);
            line = line.trim();
        } catch (Exception e) {
            throw new Exception("Line \"{0}\",  \"{1}\"" + originalLine + " "
                                + line + " " + e.toString());
        }
        return line;
    }
}

//eof
