/*
 *  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.directory.server.benchmarks;


import java.util.ArrayList;
import java.util.Date;

import netscape.ldap.LDAPConnection;
import netscape.ldap.LDAPConstraints;
import netscape.ldap.LDAPException;

import com.sun.slamd.job.JobClass;
import com.sun.slamd.job.UnableToRunException;
import com.sun.slamd.parameter.BooleanParameter;
import com.sun.slamd.parameter.IntegerParameter;
import com.sun.slamd.parameter.InvalidValueException;
import com.sun.slamd.parameter.Parameter;
import com.sun.slamd.parameter.ParameterList;
import com.sun.slamd.parameter.PasswordParameter;
import com.sun.slamd.parameter.PlaceholderParameter;
import com.sun.slamd.parameter.StringParameter;
import com.sun.slamd.stat.IncrementalTracker;
import com.sun.slamd.stat.RealTimeStatReporter;
import com.sun.slamd.stat.StatTracker;
import com.sun.slamd.stat.TimeTracker;


/**
 * A simple bind benchmark.  Here the same bindDn and password is 
 * used to bind to the directory.  The connection to the directory is
 * by default shared across iterations of a thread but this can be 
 * changed.  This is not a real world experiment but a way for us to
 * stress test the server, profile it, optimize it and regression test
 * our results under stress for more reliable feedback.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class BindBenchmark extends JobClass
{
    /**
     * The name of the stat tracker that will be used to count the number of
     * authentication attempts.
     */
    public static final String STAT_TRACKER_AUTHENTICATION_ATTEMPTS = "Authentication Attempts";

    /**
     * The name of the stat tracker that will be used to keep track of the time 
     * required to perform each authentication.
     */
    public static final String STAT_TRACKER_AUTHENTICATION_TIME = "Authentication Time";

    /**
     * The name of the stat tracker that will be used to count the number of
     * failed authentications.
     */
    public static final String STAT_TRACKER_FAILED_AUTHENTICATIONS = "Failed Authentications";

    /**
     * The name of the stat tracker that will be used to count the number of
     * successful authentications.
     */
    public static final String STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS = "Successful Authentications";

    // -----------------------------------------------------------------------
    // Extracted paramter values for the whole Job
    // -----------------------------------------------------------------------

    // The connection is estabilished anew every time for each bind request
    // if this option is not selected instead of reusing the existing connection
    // for each iteration.  The default is to share the connection.
    static boolean shareConnections;
    
    // Indicates whether bind failures because of invalid credentials will be
    // ignored (so we can optimize for authn failures as well).
    static boolean ignoreInvalidCredentials;

    // The maximum number of iterations per thread.
    static int iterations;

    // The maximum length of time that any single LDAP operation will be allowed
    // to take before it is cancelled.
    static int timeLimit;

    // The time to start working before beginning statistics collection.
    static int warmUpTime;

    // The delay in milliseconds between authentication attempts.
    static long delay;

    // The port number of the directory server.
    static int directoryPort;

    // The address of the directory server.
    static String directoryHost;

    // The DN to use to bind to the directory 
    static String bindDN;

    // The password for the bind DN.
    static String bindPW;

    // -----------------------------------------------------------------------
    // Paramters definitions
    // -----------------------------------------------------------------------

    // The parameter controlling where or not connections are reused
    BooleanParameter shareConnectionsParameter = new BooleanParameter( "shareConnectionsParameter",
        "Share Connections", 
        "Specifies whether or not the connection to the LDAP server is shared or " +
        "re-estabilished every time for each iteration.  If true the iteration creates" +
        "and destroys a new connection before issueing a bind request.", true );
    
    // The parameter that indicates the delay that should be used between each
    // authentication attempt.
    IntegerParameter delayParameter = new IntegerParameter( "delay", "Time Between Authentications (ms)",
        "Specifies the length of time in milliseconds " + "each thread should wait between authentication "
            + "attempts.  Note that this delay will be " + "between the starts of consecutive attempts and "
            + "not between the end of one attempt and the " + "beginning of the next.  If an authentication "
            + "takes longer than this length of time, then " + "there will be no delay.", true, 0, true, 0, false, 0 );

    // The parameter that indicates the number of iterations to perform.
    IntegerParameter iterationsParameter = new IntegerParameter( "num_iterations", "Number of Iterations",
        "The number of authentications that should be " + "performed by each thread", false, -1 );

    // The parameter used to indicate the maximum length of time that any single
    // LDAP operation will be allowed to take.
    IntegerParameter timeLimitParameter = new IntegerParameter( "time_limit", "Operation Time Limit",
        "The maximum length of time in seconds that any " + "single LDAP operation will be allowed to take "
            + "before it is cancelled.", true, 0, true, 0, false, 0 );

    // The parmeter that specifies the cool-down time in seconds.
    IntegerParameter warmUpParameter = new IntegerParameter( "warm_up", "Warm Up Time",
        "The time in seconds that the job should " + "search before beginning statistics collection.", true, 0, true,
        0, false, 0 );

    // The placeholder parameter used as a spacer in the admin interface.
    PlaceholderParameter placeholder = new PlaceholderParameter();

    // The parameter used to indicate the port number for the directory server.
    IntegerParameter portParameter = new IntegerParameter( "ldap_port", "Directory Server Port",
        "The port number for the directory server.", true, 389, true, 1, true, 65535 );

    // The parameter used to indicate the address of the directory server.
    StringParameter hostParameter = new StringParameter( "ldap_host", "Directory Server Address",
        "The address for the directory server.", true, "" );

    // The parameter used to indicate the bind DN.
    StringParameter bindDNParameter = new StringParameter( "binddn", "Directory Bind DN",
        "The DN to use when binding to the directory server.", false, "" );

    // The parameter used to indicate the bind DN.
    PasswordParameter bindPWParameter = new PasswordParameter( "bindpw", "Bind Password",
        "The password to use when binding.", false, "" );

    // -----------------------------------------------------------------------
    // Stat trakers for each thread.
    // -----------------------------------------------------------------------

    // The stat tracker that will count the # of authentication attempts.
    IncrementalTracker attemptCounter;

    // The stat tracker that will count the # of failed authentications.
    IncrementalTracker failureCounter;

    // The stat tracker that will count the # of successful authentications.
    IncrementalTracker successCounter;

    // The stat tracker that will time each authentication.
    TimeTracker authTimer;

    // -----------------------------------------------------------------------
    // Connection and other parameters for each thread
    // -----------------------------------------------------------------------

    // The LDAP connection that will be used for bind operations by this thread.
    LDAPConnection bindConnection;

    // The set of constraints that will be used for bind operations.
    LDAPConstraints bindConstraints;


    public String getJobDescription()
    {
        return "Does a bind using a single user name then immediately unbinds.";
    }


    public String getJobName()
    {
        return "Bind/Unbind Optimization Test";
    }


    public String getJobCategoryName()
    {
        return "ApacheDS Optimization Tests";
    }


    /**
     * Returns the set of parameters whose value may be specified by the end user.
     *
     * @return  The set of configurable parameters for this job class.
     */
    public ParameterList getParameterStubs()
    {
        Parameter[] parameterArray = new Parameter[]
            { placeholder, hostParameter, portParameter, bindDNParameter, bindPWParameter, placeholder,
                warmUpParameter, timeLimitParameter, delayParameter, placeholder,
                iterationsParameter, shareConnectionsParameter };

        return new ParameterList( parameterArray );
    }


    public StatTracker[] getStatTrackerStubs( String clientID, String threadID, int collectionInterval )
    {
        return new StatTracker[]
            {
                new IncrementalTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_ATTEMPTS, collectionInterval ),
                new IncrementalTracker( clientID, threadID, STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS, collectionInterval ),
                new IncrementalTracker( clientID, threadID, STAT_TRACKER_FAILED_AUTHENTICATIONS, collectionInterval ),
                new TimeTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_TIME, collectionInterval ) };
    }


    public StatTracker[] getStatTrackers()
    {
        return new StatTracker[]
            { attemptCounter, successCounter, failureCounter, authTimer };
    }


    public void validateJobInfo( int numClients, int threadsPerClient, int threadStartupDelay, Date startTime,
        Date stopTime, int duration, int collectionInterval, ParameterList parameters ) throws InvalidValueException
    {
        // might want to add something here later
    }


    public boolean providesParameterTest()
    {
        return true;
    }


    /**
     * Provides a means of testing the provided job parameters to determine
     * whether they are valid (e.g., to see if the server is reachable) before
     * scheduling the job for execution.  This method will be executed by the
     * SLAMD server system itself and not by any of the clients.
     *
     * @param  parameters      The job parameters to be tested.
     * @param  outputMessages  The lines of output that were generated as part of
     *                         the testing process.  Each line of output should
     *                         be added to this list as a separate string, and
     *                         empty strings (but not <CODE>null</CODE> values)
     *                         are allowed to provide separation between
     *                         different messages.  No formatting should be
     *                         provided for these messages, however, since they
     *                         may be displayed in either an HTML or plain text
     *                         interface.
     *
     * @return  <CODE>true</CODE> if the test completed successfully, or
     *          <CODE>false</CODE> if not. 
     */
    public boolean testJobParameters( ParameterList parameters, ArrayList outputMessages )
    {
        // Get all the parameters that we might need to perform the test.
        StringParameter hostParam = parameters.getStringParameter( hostParameter.getName() );
        if ( ( hostParam == null ) || ( !hostParam.hasValue() ) )
        {
            outputMessages.add( "ERROR:  No directory server address was provided." );
            return false;
        }
        String host = hostParam.getStringValue();

        IntegerParameter portParam = parameters.getIntegerParameter( portParameter.getName() );
        if ( ( portParam == null ) || ( !hostParam.hasValue() ) )
        {
            outputMessages.add( "ERROR:  No directory server port was provided." );
            return false;
        }
        int port = portParam.getIntValue();

        String bindDN = "";
        StringParameter bindDNParam = parameters.getStringParameter( bindDNParameter.getName() );
        if ( ( bindDNParam != null ) && bindDNParam.hasValue() )
        {
            bindDN = bindDNParam.getStringValue();
        }

        String bindPassword = "";
        PasswordParameter bindPWParam = parameters.getPasswordParameter( bindPWParameter.getName() );
        if ( ( bindPWParam != null ) && bindPWParam.hasValue() )
        {
            bindPassword = bindPWParam.getStringValue();
        }

        // Create the LDAPConnection object that we will use to communicate with the directory server.
        LDAPConnection conn = new LDAPConnection();

        // Attempt to establish a connection to the directory server.
        try
        {
            outputMessages.add( "Attempting to establish a connection to " + host + ":" + port + "...." );
            conn.connect( host, port );
            outputMessages.add( "Connected successfully." );
            outputMessages.add( "" );
        }
        catch ( Exception e )
        {
            outputMessages.add( "ERROR:  Unable to connect to the directory " + "server:  " + stackTraceToString( e ) );
            return false;
        }

        // Attempt to bind to the directory server using the bind DN and password.
        try
        {
            outputMessages.add( "Attempting to perform an LDAPv3 bind to the " + "directory server with a DN of '"
                + bindDN + "'...." );
            conn.bind( 3, bindDN, bindPassword );
            outputMessages.add( "Bound successfully." );
            outputMessages.add( "" );
        }
        catch ( Exception e )
        {
            try
            {
                conn.disconnect();
            }
            catch ( Exception e2 )
            {
            }

            outputMessages.add( "ERROR:  Unable to bind to the directory server:  " + stackTraceToString( e ) );
            return false;
        }

        // At this point, all tests have passed.  Close the connection and return true.
        try
        {
            conn.disconnect();
        }
        catch ( Exception e )
        {
        }

        outputMessages.add( "All tests completed successfully." );
        return true;
    }


    /**
     * Performs initialization for this job on each client immediately before each
     * thread is created to actually run the job.
     *
     * @param  clientID    The ID assigned to the client running this job.
     * @param  parameters  The set of parameters provided to this job that can be
     *                     used to customize its behavior.
     *
     * @throws  UnableToRunException  If the client initialization could not be
     *                                completed successfully and the job is unable
     *                                to run.
     */
    public void initializeClient( String clientID, ParameterList parameters ) throws UnableToRunException
    {
        // Get the shareConnections boolean parameter
        shareConnectionsParameter = parameters.getBooleanParameter( shareConnectionsParameter.getName() );
        if ( hostParameter == null )
        {
            shareConnections = true; // the default
        }
        else
        {
            shareConnections = shareConnectionsParameter.getBooleanValue();
        }
        
        
        // Get the directory server address
        hostParameter = parameters.getStringParameter( hostParameter.getName() );
        if ( hostParameter == null )
        {
            throw new UnableToRunException( "No directory server host provided." );
        }
        else
        {
            directoryHost = hostParameter.getStringValue();
        }

        // Get the directory server port
        portParameter = parameters.getIntegerParameter( portParameter.getName() );
        if ( portParameter != null )
        {
            directoryPort = portParameter.getIntValue();
        }

        // Get the DN to use to bind to the directory server.
        bindDNParameter = parameters.getStringParameter( bindDNParameter.getName() );
        if ( bindDNParameter == null )
        {
            bindDN = "";
        }
        else
        {
            bindDN = bindDNParameter.getStringValue();
        }

        // Get the password to use to bind to the directory server.
        bindPWParameter = parameters.getPasswordParameter( bindPWParameter.getName() );
        if ( bindPWParameter == null )
        {
            bindPW = "";
        }
        else
        {
            bindPW = bindPWParameter.getStringValue();
        }

        // Get the warm up time.
        warmUpTime = 0;
        warmUpParameter = parameters.getIntegerParameter( warmUpParameter.getName() );
        if ( warmUpParameter != null )
        {
            warmUpTime = warmUpParameter.getIntValue();
        }

        // Get the max operation time limit.
        timeLimitParameter = parameters.getIntegerParameter( timeLimitParameter.getName() );
        if ( timeLimitParameter != null )
        {
            timeLimit = timeLimitParameter.getIntValue();
        }

        // Get the delay between authentication attempts.
        delay = 0;
        delayParameter = parameters.getIntegerParameter( delayParameter.getName() );
        if ( delayParameter != null )
        {
            delay = delayParameter.getIntValue();
        }

        // Get the number of iterations to perform.
        iterations = -1;
        iterationsParameter = parameters.getIntegerParameter( iterationsParameter.getName() );
        if ( ( iterationsParameter != null ) && ( iterationsParameter.hasValue() ) )
        {
            iterations = iterationsParameter.getIntValue();
        }
    }


    public void initializeThread( String clientID, String threadID, int collectionInterval, ParameterList parameters )
        throws UnableToRunException
    {
        if ( shareConnections )
        {
            bindConnection = new LDAPConnection();
    
            try
            {
                bindConnection.connect( 3, directoryHost, directoryPort, "", "" );
            }
            catch ( Exception e )
            {
                throw new UnableToRunException( "Unable to establish the connections " + "to the directory server:  " + e,
                    e );
            }
    
            // Initialize the constraints.
            bindConstraints = bindConnection.getConstraints();
            bindConstraints.setTimeLimit( 1000 * timeLimit );
        }
    
        // Create the stat trackers.
        attemptCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_ATTEMPTS,
            collectionInterval );
        successCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_SUCCESSFUL_AUTHENTICATIONS,
            collectionInterval );

        failureCounter = new IncrementalTracker( clientID, threadID, STAT_TRACKER_FAILED_AUTHENTICATIONS,
            collectionInterval );
        authTimer = new TimeTracker( clientID, threadID, STAT_TRACKER_AUTHENTICATION_TIME, collectionInterval );

        // Enable real-time reporting of the data for these stat trackers.
        RealTimeStatReporter statReporter = getStatReporter();
        if ( statReporter != null )
        {
            String jobID = getJobID();
            attemptCounter.enableRealTimeStats( statReporter, jobID );
            successCounter.enableRealTimeStats( statReporter, jobID );
            failureCounter.enableRealTimeStats( statReporter, jobID );
            authTimer.enableRealTimeStats( statReporter, jobID );
        }
    }


    /**
     * Performs the work of actually running the job.  When this method completes,
     * the job will be done.
     */
    public void runJob()
    {
        // Determine the range of time for which we should collect statistics.
        long currentTime = System.currentTimeMillis();
        boolean collectingStats = false;
        long startCollectingTime = currentTime + ( 1000 * warmUpTime );
        long stopCollectingTime = Long.MAX_VALUE;

        // See if this thread should operate "infinitely" (i.e., not a fixed number of iterations)
        boolean infinite = ( iterations <= 0 );

        // Loop until it is time to stop.
        for ( int ii = 0; !shouldStop() && ( infinite || ii < iterations ); ii++ )
        {
            currentTime = System.currentTimeMillis();

            if ( ( !collectingStats ) && ( currentTime >= startCollectingTime ) && ( currentTime < stopCollectingTime ) )
            {
                // Start all the stat trackers.
                attemptCounter.startTracker();
                successCounter.startTracker();
                failureCounter.startTracker();
                authTimer.startTracker();
                collectingStats = true;
            }
            else if ( ( collectingStats ) && ( currentTime >= stopCollectingTime ) )
            {
                // Stop all the stat trackers.
                attemptCounter.stopTracker();
                successCounter.stopTracker();
                failureCounter.stopTracker();
                authTimer.stopTracker();
                collectingStats = false;
            }

            // See if we need to sleep before the next attempt
            if ( delay > 0 )
            {
                long now = System.currentTimeMillis();
                long sleepTime = delay - now;

                if ( sleepTime > 0 )
                {
                    try
                    {
                        Thread.sleep( sleepTime );
                    }
                    catch ( InterruptedException ie )
                    {
                    }

                    if ( shouldStop() )
                    {
                        break;
                    }
                }
            }

            if ( ! shareConnections )
            {
                bindConnection = new LDAPConnection();
                
                try
                {
                    bindConnection.connect( 3, directoryHost, directoryPort, "", "" );
                }
                catch ( Exception e )
                {
                    throw new IllegalStateException( "Unable to establish the connections " 
                        + "to the directory server:  " + e, e );
                }
        
                // Initialize the constraints.
                bindConstraints = bindConnection.getConstraints();
                bindConstraints.setTimeLimit( 1000 * timeLimit );
            }

            if ( collectingStats )
            {
                attemptCounter.increment();
                authTimer.startTimer();
            }

            // Increment the number of authentication attempts and start the timer
            try
            {
                // Perform a bind as the user to verify that the provided password is
                // valid.
                bindConnection.authenticate( 3, bindDN, bindPW );
                if ( collectingStats )
                {
                    successCounter.increment();
                    authTimer.stopTimer();
                }
            }
            catch ( LDAPException le )
            {
                if ( !( ignoreInvalidCredentials && ( le.getLDAPResultCode() == LDAPException.INVALID_CREDENTIALS ) ) )
                {
                    if ( collectingStats )
                    {
                        failureCounter.increment();
                        authTimer.stopTimer();
                    }
                }
                
                StringBuffer buf = new StringBuffer();
                buf.append( "LDAPException: " ).append( le.getMessage() )
                    .append( " - " ).append( le.getLDAPErrorMessage() );
                writeVerbose( buf.toString() );
            }
            finally
            {
                if ( ! shareConnections )
                {
                    if ( bindConnection != null )
                    {
                        try
                        {
                            bindConnection.disconnect();
                        }
                        catch ( Exception e )
                        {
                        }
            
                        bindConnection = null;
                    }
                }
            }
        }

        attemptCounter.stopTracker();
        successCounter.stopTracker();
        failureCounter.stopTracker();
        authTimer.stopTracker();
    }


    /**
     * Attempts to force this thread to exit by closing the connections to the
     * directory server and setting them to <CODE>null</CODE>.
     */
    public void destroy()
    {
        if ( shareConnections )
        {
            if ( bindConnection != null )
            {
                try
                {
                    bindConnection.disconnect();
                }
                catch ( Exception e )
                {
                }
    
                bindConnection = null;
            }
        }
    }
}
