

package gov.va.med.cds.monitor;


import gov.va.med.cds.monitor.util.MetricsCalculator;


public abstract class AbstractMethodMetrics
    implements
        MethodMetricsInterface
{
    private boolean collectionEnabled = false;
    private long methodCount = 0;
    private long methodElapsedTime = 0;
    private long minElapsedTime = Long.MAX_VALUE;
    private long maxElapsedTime = Long.MIN_VALUE;
    private double averageElapsedTime = 0.0;
    private double transactionsPerSecond = 0.0;


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#isCollectionEnabled()
     */
    public boolean isCollectionEnabled( )
    {
        return collectionEnabled;
    }


    private synchronized void setCollectionEnabled( boolean enabled )
    {
        if ( enabled == true )
        {
            resetMetrics();
        }
        collectionEnabled = enabled;
    }


    /**
     * Sets collection of metrics bean to true which may result in resetting metric values to intial starting points.
     */
    public synchronized void enableMetrics( )
    {
        setCollectionEnabled( true );
    }


    /**
     * Sets collection of metrics to false - this will maintain the metric settings until the metrics bean is re-enabled
     *
     */
    public synchronized void disableMetrics( )
    {
        setCollectionEnabled( false );
    }


    public synchronized void resetMetrics( )
    {
        methodCount = 0;
        methodElapsedTime = 0;
        minElapsedTime = Long.MAX_VALUE;
        maxElapsedTime = Long.MIN_VALUE;
        averageElapsedTime = 0.0;
        transactionsPerSecond = 0.0;
    }


    /**
     * Adds an elapsed time to the statistics
     *
     * @param elapsedTime
     */
    public synchronized void setSingleMethodElapsedTime( long elapsedTime )
    {
        if ( collectionEnabled )
        {
            methodElapsedTime += elapsedTime;
            methodCount++ ;
            averageElapsedTime = ( double )methodElapsedTime / methodCount; // division of ints doesn't retain precision
            transactionsPerSecond = MetricsCalculator.getTransactionsPerSecond( methodCount, methodElapsedTime );
            minElapsedTime = Math.min( minElapsedTime, elapsedTime );
            maxElapsedTime = Math.max( maxElapsedTime, elapsedTime );
        }
    }


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#getTransactions()
     */
    protected long getTransactions( )
    {
        return methodCount;
    }


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#getElapsedTime()
     */
    protected long getElapsedTime( )
    {
        return methodElapsedTime;
    }


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#getTransactionsPerSecond()
     */
    protected double getTransactionsPerSecond( )
    {
        return transactionsPerSecond;
    }


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#getAverageElapsedTime()
     */
    protected double getAverageElapsedTime( )
    {
        return averageElapsedTime;
    }


    protected long getMaxElapsedTime( )
    {
        return maxElapsedTime;
    }


    /*
     * (non-Javadoc)
     *
     * @see gov.va.med.cds.monitor.MethodMetricsInterface#getMinElapsedTime()
     */
    protected long getMinElapsedTime( )
    {
        return minElapsedTime;
    }
}
