/*
 * $Id$
 * 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.commons.ognl.test;

import org.apache.commons.ognl.Ognl;
import org.apache.commons.ognl.OgnlContext;
import org.apache.commons.ognl.OgnlException;
import org.apache.commons.ognl.SimpleNode;
import org.apache.commons.ognl.test.objects.Bean1;

import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class Performance
{

    private static int MAX_ITERATIONS = -1;

    private static boolean ITERATIONS_MODE;

    private static long MAX_TIME = -1L;

    private static boolean TIME_MODE;

    private static final NumberFormat FACTOR_FORMAT = new DecimalFormat( "0.000" );

    private final String _name;

    private final OgnlContext _context = (OgnlContext) Ognl.createDefaultContext( null );

    private final Bean1 _root = new Bean1();

    private SimpleNode _expression;

    private SimpleNode _compiledExpression;

    private final Method _method;

    private int _iterations;

    private final String _expressionString;

    private boolean _isMvel = false;

    private long t0;

    private long t1;

    /*
     * =================================================================== Private static classes
     * ===================================================================
     */
    private static class Results
    {

        int iterations;

        long time;

        boolean mvel;

        public Results( int iterations, long time, boolean mvel )
        {
            this.iterations = iterations;
            this.time = time;
            this.mvel = mvel;
        }

        public String getFactor( Results otherResults )
        {
            String ret;

            if ( TIME_MODE )
            {
                float factor;

                if ( iterations < otherResults.iterations )
                {
                    factor =
                        Math.max( (float) otherResults.iterations, (float) iterations )
                            / Math.min( (float) otherResults.iterations, (float) iterations );
                }
                else
                {
                    factor =
                        Math.min( (float) otherResults.iterations, (float) iterations )
                            / Math.max( (float) otherResults.iterations, (float) iterations );
                }

                ret = FACTOR_FORMAT.format( factor );
                if ( iterations > otherResults.iterations )
                    ret += " times faster than ";
                else
                    ret += " times slower than ";

            }
            else
            {
                float factor =
                    Math.max( (float) otherResults.time, (float) time )
                        / Math.min( (float) otherResults.time, (float) time );

                ret = FACTOR_FORMAT.format( factor );
                if ( time < otherResults.time )
                    ret += " times faster than ";
                else
                    ret += " times slower than ";
            }

            return ret;
        }
    }

    /*
     * =================================================================== Public static methods
     * ===================================================================
     */
    public static void main( String[] args )
    {
        for ( int i = 0; i < args.length; i++ )
        {
            if ( args[i].equals( "-time" ) )
            {
                TIME_MODE = true;
                MAX_TIME = Long.parseLong( args[++i] );
            }
            else if ( args[i].equals( "-iterations" ) )
            {
                ITERATIONS_MODE = true;
                MAX_ITERATIONS = Integer.parseInt( args[++i] );
            }
        }
        if ( !TIME_MODE && !ITERATIONS_MODE )
        {
            TIME_MODE = true;
            MAX_TIME = 1500;
        }

        try
        {
            Performance[] tests =
                new Performance[] {
                    new Performance( "Constant", "100 + 20 * 5", "testConstantExpression" ),
                    // new Performance("Constant", "100 + 20 * 5", "testConstantExpression", false),
                    new Performance( "Single Property", "bean2", "testSinglePropertyExpression" ),
                    new Performance( "Property Navigation", "bean2.bean3.value", "testPropertyNavigationExpression" ),
                    /*
                     * new Performance("Property Setting with context key", "bean2.bean3.nullValue",
                     * "testPropertyNavigationSetting"), new Performance("Property Setting with context key",
                     * "bean2.bean3.nullValue", "testPropertyNavigationSetting", true),
                     */
                    new Performance( "Property Navigation and Comparison", "bean2.bean3.value <= 24",
                                     "testPropertyNavigationAndComparisonExpression" ),
                    /*
                     * new Performance("Property Navigation with Indexed Access", "bean2.bean3.indexedValue[25]",
                     * "testIndexedPropertyNavigationExpression"), new
                     * Performance("Property Navigation with Indexed Access", "bean2.bean3.indexedValue[25]",
                     * "testIndexedPropertyNavigationExpression", true),
                     */
                    new Performance( "Property Navigation with Map Access", "bean2.bean3.map['foo']",
                                     "testPropertyNavigationWithMapExpression" ),
                /*
                 * new Performance("Property Navigation with Map value set", "bean2.bean3.map['foo']",
                 * "testPropertyNavigationWithMapSetting"), new Performance("Property Navigation with Map value set",
                 * "bean2.bean3.map['foo']", "testPropertyNavigationWithMapSetting", true)
                 */
                };

            boolean timeMode = TIME_MODE;
            boolean iterMode = ITERATIONS_MODE;
            long maxTime = MAX_TIME;
            int maxIterations = MAX_ITERATIONS;

            // TIME_MODE = false;
            // ITERATIONS_MODE = true;
            // maxIterations = 1000;

            runTests( tests, false );

            TIME_MODE = timeMode;
            ITERATIONS_MODE = iterMode;
            MAX_TIME = maxTime;
            MAX_ITERATIONS = maxIterations;

            System.out.println( "\n\n============================================================================\n" );

            Thread.sleep( 2500 );
            runTests( tests, true );

            // Thread.sleep(2000);

            System.out.println( "\n\n============================================================================\n" );
            // runTests(tests);

        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
        }
    }

    static void runTests( Performance[] tests, boolean output )
        throws Exception
    {
        for ( Performance perf : tests )
        {
            try
            {

                Results javaResults = perf.testJava( ), interpretedResults = perf.testExpression( false ),
                    compiledResults = perf.testExpression( true );

                if ( !output )
                {
                    return;
                }

                System.out.println( ( compiledResults.mvel ? "MVEL" : "OGNL" ) + " " + perf.getName( ) + ": "
                                        + perf.getExpression( ) );
                System.out.println(
                    "       java: " + javaResults.iterations + " iterations in " + javaResults.time + " ms" );

                System.out.println(
                    "   compiled: " + compiledResults.iterations + " iterations in " + compiledResults.time + " ms ("
                        + compiledResults.getFactor( javaResults ) + "java)" );

                System.out.println(
                    "interpreted: " + interpretedResults.iterations + " iterations in " + interpretedResults.time
                        + " ms (" + interpretedResults.getFactor( javaResults ) + "java)" );

                System.out.println( );

            }
            catch ( OgnlException ex )
            {
                ex.printStackTrace( );
            }
        }
    }

    /*
     * =================================================================== Constructors
     * ===================================================================
     */
    public Performance( String name, String expressionString, String javaMethodName )
        throws Exception
    {
        this( name, expressionString, javaMethodName, false );
    }

    public Performance( String name, String expressionString, String javaMethodName, boolean mvel )
        throws Exception
    {
        _name = name;
        _isMvel = mvel;
        _expressionString = expressionString;

        try
        {
            _method = getClass().getMethod( javaMethodName );
        }
        catch ( Exception ex )
        {
            throw new OgnlException( "java method not found", ex );
        }

        if ( !_isMvel )
        {
            _expression = (SimpleNode) Ognl.parseExpression( expressionString );
            _compiledExpression = (SimpleNode) Ognl.compileExpression( _context, _root, expressionString );
            Ognl.getValue( _expression, _context, _root );
            _context.put( "contextValue", "cvalue" );
        }
        else
        {
            // _mvelCompiled = MVEL.compileExpression(expressionString);
        }
    }

    /*
     * =================================================================== Protected methods
     * ===================================================================
     */
    protected void startTest()
    {
        _iterations = 0;
        t0 = t1 = System.currentTimeMillis();
    }

    protected Results endTest()
    {
        return new Results( _iterations, t1 - t0, _isMvel );
    }

    protected boolean done()
    {
        _iterations++;
        t1 = System.currentTimeMillis();

        if ( TIME_MODE )
        {
            return ( t1 - t0 ) >= MAX_TIME;
        }
        else
        {
            if ( ITERATIONS_MODE )
            {
                return _iterations >= MAX_ITERATIONS;
            }
            else
            {
                throw new RuntimeException( "no maximums specified" );
            }
        }
    }

    /*
     * =================================================================== Public methods
     * ===================================================================
     */
    public String getName()
    {
        return _name;
    }

    public String getExpression()
    {
        return _expressionString;
    }

    public Results testExpression( boolean compiled )
        throws Exception
    {
        startTest();
        do
        {
            if ( !_isMvel )
            {
                if ( compiled )
                    Ognl.getValue( _compiledExpression.getAccessor(), _context, _root );
                else
                    Ognl.getValue( _expression, _context, _root );
            }
            else
            {
                /*
                 * if (compiled) MVEL.executeExpression(_mvelCompiled, _root); else MVEL.eval(_expressionString, _root);
                 */
            }
        }
        while ( !done() );
        return endTest();
    }

    public Results testJava()
        throws OgnlException
    {
        try
        {
            return (Results) _method.invoke( this );
        }
        catch ( Exception ex )
        {
            throw new OgnlException( "invoking java method '" + _method.getName() + "'", ex );
        }
    }

    public Results testConstantExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            @SuppressWarnings( "unused" )
            int result = 100 + 20 * 5;
        }
        while ( !done() );
        return endTest();
    }

    public Results testSinglePropertyExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2();
        }
        while ( !done() );
        return endTest();
    }

    public Results testPropertyNavigationExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2().getBean3().getValue();
        }
        while ( !done() );
        return endTest();
    }

    public Results testPropertyNavigationSetting()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2().getBean3().setNullValue( "a value" );
        }
        while ( !done() );
        return endTest();
    }

    public Results testPropertyNavigationAndComparisonExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            @SuppressWarnings( "unused" )
            boolean result = _root.getBean2().getBean3().getValue() < 24;
        }
        while ( !done() );
        return endTest();
    }

    public Results testIndexedPropertyNavigationExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2().getBean3().getIndexedValue( 25 );
        }
        while ( !done() );
        return endTest();
    }

    public Results testPropertyNavigationWithMapSetting()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2().getBean3().getMap().put( "bam", "bam" );
        }
        while ( !done() );
        return endTest();
    }

    public Results testPropertyNavigationWithMapExpression()
        throws OgnlException
    {
        startTest();
        do
        {
            _root.getBean2().getBean3().getMap().get( "foo" );
        }
        while ( !done() );
        return endTest();
    }
}
