package org.apache.commons.jcs3.access;

/*
 * 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.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;

import org.apache.commons.jcs3.engine.control.event.ElementEventHandlerMockImpl;
import org.apache.commons.jcs3.JCS;
import org.apache.commons.jcs3.access.CacheAccess;
import org.apache.commons.jcs3.access.GroupCacheAccess;
import org.apache.commons.jcs3.access.exception.CacheException;
import org.apache.commons.jcs3.engine.ElementAttributes;
import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
import org.apache.commons.jcs3.engine.control.CompositeCacheManager;
import org.apache.commons.jcs3.log.Log;
import org.apache.commons.jcs3.log.LogManager;

/**
 * Allows the user to run common cache commands from the command line for a test cache. This also
 * provide basic methods for use in unit tests.
 */
public class TestCacheAccess
{
    /** log instance */
    private static final Log log = LogManager.getLog( TestCacheAccess.class );

    /** cache instance to use in testing */
    private CacheAccess<String, String> cache_control = null;

    /** cache instance to use in testing */
    private GroupCacheAccess<String, String> group_cache_control = null;

    /** do we use system.out.println to print out debug data? */
    private static boolean isSysOut = false;

    /** Construct and initialize the cachecontrol based on the config file. */
    public TestCacheAccess()
    {
        this( "testCache1" );
    }

    /**
     * @param regionName the name of the region.
     */
    public TestCacheAccess( String regionName )
    {
        try
        {
            cache_control = JCS.getInstance( regionName );
            group_cache_control = JCS.getGroupCacheInstance( regionName );
        }
        catch ( Exception e )
        {
            log.error( "Problem getting cache instance", e );
            p( e.toString() );
        }
    }

    /**
     * This is the main loop called by the main method.
     */
    public void runLoop()
    {
        try
        {
            // process user input till done
            boolean notDone = true;
            String message = null;
            // wait to dispose
            BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );

            help();

            while ( notDone )
            {
                p( "enter command:" );

                message = br.readLine();

                if ( message == null || message.startsWith( "help" ) )
                {
                    help();
                }
                else if ( message.startsWith( "gc" ) )
                {
                    System.gc();
                }
                else if ( message.startsWith( "getAttributeNames" ) )
                {
                    long n_start = System.currentTimeMillis();
                    String groupName = null;
                    StringTokenizer toke = new StringTokenizer( message );
                    int tcnt = 0;
                    while ( toke.hasMoreElements() )
                    {
                        tcnt++;
                        String t = (String) toke.nextElement();
                        if ( tcnt == 2 )
                        {
                            groupName = t.trim();
                        }
                    }
                    getAttributeNames( groupName );
                    long n_end = System.currentTimeMillis();
                    p( "---got attrNames for " + groupName + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
                }
                else if ( message.startsWith( "shutDown" ) )
                {
                    CompositeCacheManager.getInstance().shutDown();
                    //cache_control.dispose();
                    notDone = false;
                    //System.exit( -1 );
                    return;
                }
                /////////////////////////////////////////////////////////////////////
                // get multiple from a region
                else if ( message.startsWith( "getm" ) )
                {
                    processGetMultiple( message );
                }
                else if ( message.startsWith( "getg" ) )
                {
                    processGetGroup( message );
                }
                else if ( message.startsWith( "getag" ) )
                {
                    processGetAutoGroup( message );
                }
                else if ( message.startsWith( "getMatching" ) )
                {
                    processGetMatching( message );
                }
                else if ( message.startsWith( "get" ) )
                {
                    processGet( message );
                }
                else if ( message.startsWith( "putg" ) )
                {
                    processPutGroup( message );
                }
                // put automatically
                else if ( message.startsWith( "putag" ) )
                {
                    processPutAutoGroup( message );
                }
                else if ( message.startsWith( "putm" ) )
                {
                    String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
                    if ( numS == null )
                    {
                        p( "usage: putm numbertoput" );
                    }
                    else
                    {
                        int num = Integer.parseInt( numS.trim() );
                        putMultiple( num );
                    }
                }
                else if ( message.startsWith( "pute" ) )
                {
                    String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
                    if ( numS == null )
                    {
                        p( "usage: putme numbertoput" );
                    }
                    else
                    {
                        int num = Integer.parseInt( numS.trim() );
                        long n_start = System.currentTimeMillis();
                        for ( int n = 0; n < num; n++ )
                        {
                            IElementAttributes attrp = cache_control.getDefaultElementAttributes();
                            ElementEventHandlerMockImpl hand = new ElementEventHandlerMockImpl();
                            attrp.addElementEventHandler( hand );
                            cache_control.put( "key" + n, "data" + n + " put from ta = junk", attrp );
                        }
                        long n_end = System.currentTimeMillis();
                        p( "---put " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
                    }
                }
                else if ( message.startsWith( "put" ) )
                {
                    processPut( message );
                }
                else if ( message.startsWith( "removem" ) )
                {
                    String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
                    if ( numS == null )
                    {
                        p( "usage: removem numbertoremove" );
                    }
                    else
                    {
                        int num = Integer.parseInt( numS.trim() );
                        removeMultiple( num );
                    }
                }
                else if ( message.startsWith( "removeall" ) )
                {
                    cache_control.clear();
                    p( "removed all" );
                }
                else if ( message.startsWith( "remove" ) )
                {
                    String key = message.substring( message.indexOf( " " ) + 1, message.length() );
                    cache_control.remove( key );
                    p( "removed " + key );
                }
                else if ( message.startsWith( "deattr" ) )
                {
                    IElementAttributes ae = cache_control.getDefaultElementAttributes();
                    p( "Default IElementAttributes " + ae );
                }
                else if ( message.startsWith( "cloneattr" ) )
                {
                    String numS = message.substring( message.indexOf( " " ) + 1, message.length() );
                    if ( numS == null )
                    {
                        p( "usage: put numbertoput" );
                    }
                    else
                    {
                        int num = Integer.parseInt( numS.trim() );
                        IElementAttributes attrp = new ElementAttributes();
                        long n_start = System.currentTimeMillis();
                        for ( int n = 0; n < num; n++ )
                        {
                            attrp.clone();
                        }
                        long n_end = System.currentTimeMillis();
                        p( "---cloned attr " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
                    }
                }
                else if ( message.startsWith( "switch" ) )
                {
                    String name = message.substring( message.indexOf( " " ) + 1, message.length() );

                    setRegion( name );
                    p( "switched to cache = " + name );
                    p( cache_control.toString() );
                }
                else if ( message.startsWith( "stats" ) )
                {
                    p( cache_control.getStats() );
                }
                else if ( message.startsWith( "gc" ) )
                {
                    System.gc();
                    p( "Called system.gc()" );
                }
                else if ( message.startsWith( "random" ) )
                {
                    processRandom( message );
                }
            }
        }
        catch ( CacheException | IOException e )
        {
            p( e.toString() );
            e.printStackTrace( System.out );
        }
    }

    /**
     * @param message
     */
    private void processGetMultiple( String message )
    {
        int num = 0;
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                try
                {
                    num = Integer.parseInt( t.trim() );
                }
                catch ( NumberFormatException nfe )
                {
                    p( t + "not a number" );
                }
            }
            else if ( tcnt == 3 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        if ( tcnt < 2 )
        {
            p( "usage: get numbertoget show values[true|false]" );
        }
        else
        {
            getMultiple( num, show );
        }
    }

    /**
     * @param message
     */
    private void processGetGroup( String message )
    {
        String key = null;
        String group = null;
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                key = t.trim();
            }
            else if ( tcnt == 3 )
            {
                group = t.trim();
            }
            else if ( tcnt == 4 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        if ( tcnt < 2 )
        {
            p( "usage: get key show values[true|false]" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            try
            {
                Object obj = group_cache_control.getFromGroup( key, group );
                if ( show && obj != null )
                {
                    p( obj.toString() );
                }
            }
            catch ( Exception e )
            {
                log.error( e );
            }
            long n_end = System.currentTimeMillis();
            p( "---got " + key + " from group " + group + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     */
    private void processGetAutoGroup( String message )
    {
        // get auto from group

        int num = 0;
        String group = null;
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                num = Integer.parseInt( t.trim() );
            }
            else if ( tcnt == 3 )
            {
                group = t.trim();
            }
            else if ( tcnt == 4 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        if ( tcnt < 2 )
        {
            p( "usage: get key show values[true|false]" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            try
            {
                for ( int a = 0; a < num; a++ )
                {
                    Object obj = group_cache_control.getFromGroup( "keygr" + a, group );
                    if ( show && obj != null )
                    {
                        p( obj.toString() );
                    }
                }
            }
            catch ( Exception e )
            {
                log.error( e );
            }
            long n_end = System.currentTimeMillis();
            p( "---got " + num + " from group " + group + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     * @throws CacheException
     */
    private void processPutGroup( String message )
        throws CacheException
    {
        String group = null;
        String key = null;
        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                key = t.trim();
            }
            else if ( tcnt == 3 )
            {
                group = t.trim();
            }
        }

        if ( tcnt < 3 )
        {
            p( "usage: putg key group" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            group_cache_control.putInGroup( key, group, "data from putg ----asdfasfas-asfasfas-asfas in group " + group );
            long n_end = System.currentTimeMillis();
            p( "---put " + key + " in group " + group + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     * @throws CacheException
     */
    private void processPutAutoGroup( String message )
        throws CacheException
    {
        String group = null;
        int num = 0;
        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                num = Integer.parseInt( t.trim() );
            }
            else if ( tcnt == 3 )
            {
                group = t.trim();
            }
        }

        if ( tcnt < 3 )
        {
            p( "usage: putag num group" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            for ( int a = 0; a < num; a++ )
            {
                group_cache_control.putInGroup( "keygr" + a, group, "data " + a
                    + " from putag ----asdfasfas-asfasfas-asfas in group " + group );
            }
            long n_end = System.currentTimeMillis();
            p( "---put " + num + " in group " + group + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     * @throws CacheException
     */
    private void processPut( String message )
        throws CacheException
    {
        String key = null;
        String val = null;
        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                key = t.trim();
            }
            else if ( tcnt == 3 )
            {
                val = t.trim();
            }
        }

        if ( tcnt < 3 )
        {
            p( "usage: put key val" );
        }
        else
        {

            long n_start = System.currentTimeMillis();
            cache_control.put( key, val );
            long n_end = System.currentTimeMillis();
            p( "---put " + key + " | " + val + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     */
    private void processRandom( String message )
    {
        String rangeS = "";
        String numOpsS = "";
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                rangeS = t.trim();
            }
            else if ( tcnt == 3 )
            {
                numOpsS = t.trim();
            }
            else if ( tcnt == 4 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        String numS = message.substring( message.indexOf( " " ) + 1, message.length() );

        int range = 0;
        int numOps = 0;
        try
        {
            range = Integer.parseInt( rangeS.trim() );
            numOps = Integer.parseInt( numOpsS.trim() );
        }
        catch ( Exception e )
        {
            p( "usage: random range numOps show" );
            p( "ex.  random 100 1000 false" );
        }
        if ( numS == null )
        {
            p( "usage: random range numOps show" );
            p( "ex.  random 100 1000 false" );
        }
        else
        {
            random( range, numOps, show );
        }
    }

    /**
     * @param message
     */
    private void processGet( String message )
    {
        // plain old get

        String key = null;
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                key = t.trim();
            }
            else if ( tcnt == 3 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        if ( tcnt < 2 )
        {
            p( "usage: get key show values[true|false]" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            try
            {
                Object obj = cache_control.get( key );
                if ( show && obj != null )
                {
                    p( obj.toString() );
                }
            }
            catch ( Exception e )
            {
                log.error( e );
            }
            long n_end = System.currentTimeMillis();
            p( "---got " + key + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * @param message
     */
    private void processGetMatching( String message )
    {
        // plain old get

        String pattern = null;
        boolean show = true;

        StringTokenizer toke = new StringTokenizer( message );
        int tcnt = 0;
        while ( toke.hasMoreElements() )
        {
            tcnt++;
            String t = (String) toke.nextElement();
            if ( tcnt == 2 )
            {
                pattern = t.trim();
            }
            else if ( tcnt == 3 )
            {
                show = Boolean.valueOf( t ).booleanValue();
            }
        }

        if ( tcnt < 2 )
        {
            p( "usage: getMatching key show values[true|false]" );
        }
        else
        {
            long n_start = System.currentTimeMillis();
            try
            {
                Map<String, String> results = cache_control.getMatching( pattern );
                if ( show && results != null )
                {
                    p( results.toString() );
                }
            }
            catch ( Exception e )
            {
                log.error( e );
            }
            long n_end = System.currentTimeMillis();
            p( "---gotMatching [" + pattern + "] in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
    }

    /**
     * Test harness.
     * @param args The command line arguments
     */
    public static void main( String[] args )
    {
        isSysOut = true;
        String ccfFileName = args[0];
        if ( ccfFileName != null )
        {
            JCS.setConfigFilename( ccfFileName );
        }
        TestCacheAccess tca = new TestCacheAccess( "testCache1" );
        tca.runLoop();
    }

    // end main
    /////////////////////////////////////////////////////////////////////////////

    /**
     * Gets multiple items from the cache with keys of the form key1, key2, key3 up to key[num].
     * @param num int
     */
    public void getMultiple( int num )
    {
        getMultiple( num, false );
    }

    /**
     * @param num
     * @param show
     */
    public void getMultiple( int num, boolean show )
    {
        long n_start = System.currentTimeMillis();
        for ( int n = 0; n < num; n++ )
        {
            try
            {
                Object obj = cache_control.get( "key" + n );
                if ( show && obj != null )
                {
                    p( obj.toString() );
                }
            }
            catch ( Exception e )
            {
                log.error( e );
            }
        }
        long n_end = System.currentTimeMillis();
        p( "---got " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
    }

    /**
     * Puts multiple items into the cache.
     * @param num int
     */
    public void putMultiple( int num )
    {
        try
        {
            long n_start = System.currentTimeMillis();
            for ( int n = 0; n < num; n++ )
            {
                cache_control.put( "key" + n, "data" + n + " put from ta = junk" );
            }
            long n_end = System.currentTimeMillis();
            p( "---put " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
        catch ( Exception e )
        {
            log.error( e );
        }
    }

    /**
     * Removes multiple items from the cache.
     * @param num int
     */
    public void removeMultiple( int num )
    {
        try
        {
            long n_start = System.currentTimeMillis();
            for ( int n = 0; n < num; n++ )
            {
                cache_control.remove( "key" + n );
            }
            long n_end = System.currentTimeMillis();
            p( "---removed " + num + " in " + String.valueOf( n_end - n_start ) + " millis ---" );
        }
        catch ( Exception e )
        {
            log.error( e );
        }
    }

    /**
     * The random method performs numOps number of operations. The operations will be a mix of puts,
     * gets, and removes. The key range will be from 0 to range.
     * @param range int The end of the key range.
     * @param numOps int The number of operations to perform
     */
    public void random( int range, int numOps )
    {
        random( range, numOps, false );
    }

    /**
     * @param range
     * @param numOps
     * @param show
     */
    public void random( int range, int numOps, boolean show )
    {
        try
        {
            for ( int i = 1; i < numOps; i++ )
            {
                Random ran = new Random( i );
                int n = ran.nextInt( 4 );
                int kn = ran.nextInt( range );
                String key = "key" + kn;
                if ( n == 1 )
                {
                    cache_control.put( key, "data" + i + " junk asdfffffffadfasdfasf " + kn + ":" + n );
                    if ( show )
                    {
                        p( "put " + key );
                    }
                }
                else if ( n == 2 )
                {
                    cache_control.remove( key );
                    if ( show )
                    {
                        p( "removed " + key );
                    }
                }
                else
                {
                    // slightly greater chance of get
                    Object obj = cache_control.get( key );
                    if ( show && obj != null )
                    {
                        p( obj.toString() );
                    }
                }

                if ( i % 10000 == 0 )
                {
                    p( cache_control.getStats() );
                }

            }
            p( "Finished random cycle of " + numOps );
        }
        catch ( Exception e )
        {
            p( e.toString() );
            e.printStackTrace( System.out );
        }
    }

    /**
     * Sets the region to be used by test methods.
     * @param name String -- Name of region
     */
    public void setRegion( String name )
    {
        try
        {
            cache_control = JCS.getInstance( name );
        }
        catch ( Exception e )
        {
            p( e.toString() );
            e.printStackTrace( System.out );
        }

    }

    /////////////////////////////////////////////////////////////////////////////
    /**
     * The tester will print to the console if isSysOut is true, else it will log. It is false by
     * default. When run via the main method, isSysOut will be set to true
     * @param s String to print or log
     */
    public static void p( String s )
    {
        if ( isSysOut )
        {
            System.out.println( s );
        }
        else
        {
            if ( log.isDebugEnabled() )
            {
                log.debug( s );
            }
        }
    }

    /**
     * Displays usage information for command line testing.
     */
    public static void help()
    {
        p( "\n\n\n\n" );
        p( "type 'shutDown' to shutdown the cache" );
        p( "type 'getm num show[false|true]' to get num automatically from a region" );
        p( "type 'putm num' to put num automatically to a region" );
        p( "type 'removeall' to remove all items in a region" );
        p( "type 'remove key' to remove" );
        p( "type 'removem num' to remove a number automatically" );
        p( "type 'getMatching pattern show' to getMatching" );
        p( "type 'get key show' to get" );
        p( "type 'getg key group show' to get" );
        p( "type 'getag num group show' to get automatically from a group" );
        p( "type 'getAttributeNames group' to get a list og the group elements" );
        p( "type 'putg key group val' to put" );
        p( "type 'putag num group' to put automatically from a group" );
        p( "type 'put key val' to put" );
        p( "type 'stats' to get stats" );
        p( "type 'deattr' to get the default element attributes" );
        p( "type 'cloneattr num' to clone attr" );
        p( "type 'random range numOps' to put, get, and remove randomly" );
        p( "type 'switch name' to switch to this region name" );
        p( "type 'gc' to call System.gc()" );
        p( "type 'help' for commands" );

    }

    /**
     * Gets the attributeNames attribute of the TestCacheAccess class
     * @param groupName
     */
    public void getAttributeNames( String groupName )
    {
        Iterator<String> iter = group_cache_control.getGroupKeys( groupName ).iterator();

        while ( iter.hasNext() )
        {
            p( "=" + iter.next() );
        }
    }
}
