/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits réservés.
 * Ce logiciel est propriété de Sun Microsystems, Inc.
 * Distribué par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)MfTransactionMetrics.java 1.15     04/07/01 SMI"
 *
 */

package com.sun.mfwk.trans; 

import javax.management.*;
import com.sun.mfwk.util.instrum.*;
import java.util.*;
import java.util.logging.*;
import com.sun.mfwk.util.log.MfLogService;

/**
 * MfTransactionMetrics contains the computed metrics related to a transaction type
 */

public class  MfTransactionMetrics extends MfMetric 
    implements MfTransactionMetricsMBean {

    public MfTransactionMetrics() {
	// Add Timer thread
	timer = new Timer();
    }



    /**
     * Get the URI associated to the transaction metrics.
     */
    public String getUri() {
	return uri; 
    }


    /**
     * Get the number of requests received by this URI.
     */
    public long getNbInRequests() {
	return nbInRequests; 
    }


    /**
     * Get the number of requests responded by this URI.
     */
    public long getNbOutRequests() {
	return nbOutRequests; 
    }

    /**
     * Get the number of failed requests for this URI.
     */
    public long getNbFailedRequests() {
	return nbFailedRequests; 
    }

    /**
     * Get the number of aborted requests for this URI.
     */
    public long getNbAbortedRequests() {
	return nbAbortedRequests; 
    }


    ////////////////////////////////
    //
    // ResponseTime metrics getters
    //
    ////////////////////////////////

    /**
     * Get the maximum response time of this URI since the reference time.
     */
    public long getMaxResponseTime() {
	return maxResponseTime; 
    }


    /**
     * Get the minimum response time of this URI since the reference time.
     */
    public long getMinResponseTime() {
	return minResponseTime; 
    }


    /**
     * Get the accumulated response time of this URI since the reference time.
     */
    public long getAccumulatedResponseTime() {
	return accumulatedResponseTime; 
    }


    /**
     * Get the accumulated squared response time of this URI since the reference time.
     */
    public long getAccumulatedSqResponseTime() {
	return accumulatedSqResponseTime; 
    }

    ////////////////////////////////
    //
    // ServiceTime metrics getters
    //
    ////////////////////////////////


    /**
     * Get the minimum service time of this URI since the reference time.
     */
    public long  getMinServiceTime() {
	return minServiceTime; 
    }


    /**
     * Get the maximum service time of this URI since the reference time.
     */
    public long  getMaxServiceTime() {
	return maxServiceTime; 
    }


    /**
     * Get the accumulated service time of this URI since the reference time.
     */
    public long  getAccumulatedServiceTime() {
	return accumulatedServiceTime; 
    }


    /**
     * Get the accumulated squared Service time of this URI since the reference time.
     */
    public long  getAccumulatedSqServiceTime() {
	return accumulatedSqServiceTime; 
    }

    /////////////////////////////////////////////////////////////////////////////////
    //
    // Implementation of single metrics (does not take into account sub-transactions)
    //
    /////////////////////////////////////////////////////////////////////////////////

    public long  getSingleMinServiceTime() {
	return singleMinServiceTime;
    }

    public long  getSingleMaxServiceTime() {
	return singleMaxServiceTime;
    }

    public long  getSingleAccumulatedServiceTime() {
	return singleAccumulatedServiceTime;
    }

    public long  getSingleAccumulatedSqServiceTime() {
	return singleAccumulatedSqServiceTime;
    }

    public long getSingleNbFailedRequests() {
	return singleNbFailedRequests;
    }

    public long getSingleNbAbortedRequests() {
	return singleNbAbortedRequests;
    }

    /**
     * Reset all the metrics.
     */
    public synchronized void resetMetrics() {
	logger.entering("MfTransactionMetrics", "resetMetrics");

	nbInRequests = 0;
	nbOutRequests = 0;
	nbFailedRequests = 0;
	nbAbortedRequests = 0;

	minResponseTime = 0;
	maxResponseTime = 0;
	accumulatedResponseTime = 0;
	accumulatedSqResponseTime = 0;

	minServiceTime = 0;
	maxServiceTime = 0;
	accumulatedServiceTime = 0;
	accumulatedSqServiceTime = 0;

	singleMinServiceTime = 0;
	singleMaxServiceTime = 0;
	singleAccumulatedServiceTime = 0;
	singleAccumulatedSqServiceTime = 0;
	singleNbFailedRequests = 0;
	singleNbAbortedRequests = 0;
    }




    //////////////////////////////
    //
    // Protected Instance Methods
    //
    //////////////////////////////

    synchronized void setUri(String u) {
	logger.entering("MfTransactionMetrics", "setURI", u);
	uri = u;
    }


    /**
     * Set the number of requests received by this URI.
     */
    synchronized void setNbInRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setNbInRequests", new Long(nb));
	nbInRequests = nb;
    }


    /**
     * Set the number of requests responded by this URI.
     */
    synchronized void setNbOutRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setNbOutRequests", new Long(nb));
	nbOutRequests = nb;
    }


    /**
     * Set the number of failed requests for this URI.
     */
    synchronized void setNbFailedRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setNbFailedRequests", new Long(nb));
	nbFailedRequests = nb;
    }

    /**
     * Set the number of aborted requests for this URI.
     */
    synchronized void setNbAbortedRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setNbAbortedRequests", new Long(nb));
	nbAbortedRequests = nb;
    }


    /**
     * Set the maximum response time of this URI since the reference time.
     */
    synchronized void setMaxResponseTime(long time) {
	logger.entering("MfTransactionMetrics", "setMaxResponseTime", new Long(time));
	maxResponseTime = time;
    }


    /**
     * Set the minimum response time of this URI since the reference time.
     */
    synchronized void setMinResponseTime(long time) {
	logger.entering("MfTransactionMetrics", "setMinResponseTime", new Long(time));
	minResponseTime = time;
    }


    /**
     * Set the accumulated response time of this URI since the reference time.
     */
    synchronized void setAccumulatedResponseTime(long time) {
	logger.entering("MfTransactionMetrics", "setAccumulatedResponseTime", new Long(time));
	accumulatedResponseTime = time;
    }


    /**
     * Set the accumulated squared response time of this URI since the reference time.
     */
    synchronized void setAccumulatedSqResponseTime(long time) {
	logger.entering("MfTransactionMetrics", "setAccumulatedSqResponseTime", new Long(time));
	accumulatedSqResponseTime = time;
    }

    /**
     * Set the minimum service time of this URI since the reference time.
     */
    synchronized void setMinServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setMinServiceTime", new Long(time));
	minServiceTime = time;
    }


    /**
     * Set the maximum service time of this URI since the reference time.
     */
    synchronized void setMaxServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setMaxServiceTime", new Long(time));
	maxServiceTime = time;
    }


    /**
     * Set the accumulated service time of this URI since the reference time.
     */
    synchronized void setAccumulatedServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setAccumulatedServiceTime", new Long(time));
	accumulatedServiceTime = time;
    }


    /**
     * Set the accumulated squared Service time of this URI since the reference time.
     */
    synchronized void setAccumulatedSqServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setAccumulatedSqServiceTime", new Long(time));
	accumulatedSqServiceTime = time;
    }


    // Single metrics (does not take into account sub-transactions)

    synchronized void setSingleMinServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setSingleMinServiceTime", new Long(time));
	singleMinServiceTime = time;
    }

    synchronized void setSingleMaxServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setSingleMaxServiceTime", new Long(time));
	singleMaxServiceTime = time;
    }


    synchronized void setSingleAccumulatedServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setSingleAccumulatedServiceTime", new Long(time));
	singleAccumulatedServiceTime = time;
    }


    synchronized void setSingleAccumulatedSqServiceTime(long time) {
	logger.entering("MfTransactionMetrics", "setSingleAccumulatedSqServiceTime", new Long(time));
	singleAccumulatedSqServiceTime = time;
    }

    synchronized void setSingleNbFailedRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setSingleNbFailedRequests", new Long(nb));
	singleNbFailedRequests = nb;
    }

    synchronized void setSingleNbAbortedRequests(long nb) {
	logger.entering("MfTransactionMetrics", "setSingleNbAbortedRequests", new Long(nb));
	singleNbAbortedRequests = nb;
    }

    protected void handleMonitoringEnabled() {
	logger.entering("MfTransactionMetrics", "handleMonitoringEnabled");

	// Send a notification for related transactions from a new thread
	// This is mandatory to avoid deadlock !
	sendNotificationFromNewThread("MonitoringEnabled");

    }

    protected void handleMonitoringDisabled() {
	logger.entering("MfTransactionMetrics", "handleMonitoringDisabled");

	// Send a notification for related transactions from a new thread
	// This is mandatory to avoid deadlock !
	sendNotificationFromNewThread("MonitoringDisabled");
    }

    protected void sendNotificationFromNewThread(String notifType) {
	logger.entering("MfTransactionMetrics", "sendNotificationFromNewThread");
	final String type = notifType;
	TimerTask timerTask = new TimerTask() {
	    public void run() {
		logger.finest("TimerTask: Send notification: " + type);
		AttributeChangeNotification acn = new AttributeChangeNotification(
                     this, 0, 0, null, type, null, null, null);
		sendNotification(acn);
	    }
	};

	timer.schedule(timerTask, 0);
    }

    protected void finalize() throws Throwable {
	logger.entering("MfTransactionMetrics", "finalize");

	// Terminate the Timer thread
	timer.cancel();
    }

    String uri = null;
    long nbInRequests = 0;
    long nbOutRequests = 0;
    long nbFailedRequests = 0;
    long nbAbortedRequests = 0;

    long minResponseTime = 0;
    long maxResponseTime = 0;
    long accumulatedResponseTime = 0;
    long accumulatedSqResponseTime = 0;

    long minServiceTime = 0;
    long maxServiceTime = 0;
    long accumulatedServiceTime = 0;
    long accumulatedSqServiceTime = 0;

    long singleMinServiceTime = 0;
    long singleMaxServiceTime = 0;
    long singleAccumulatedServiceTime = 0;
    long singleAccumulatedSqServiceTime = 0;
    long singleNbFailedRequests = 0;
    long singleNbAbortedRequests = 0;

    private Timer timer= null;
    private static Logger logger = MfLogService.getLogger("MfTransaction");
}
