/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2009 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Release: 1.0
 *
 * Author: Eric HARDESTY
 * --------------------------------------------------------------------------
 * $Id:PoolItemStats.java
 * --------------------------------------------------------------------------
 *
 */
package org.ow2.jonas.resource.internal.pool;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** <p>This class holds information about each pool entry.
 *
 *  @author      Eric Hardesty
**/
public class PoolItemStats {

    /**
     * Each Item is given an Ident used for Admin
     */
    private static int objcount = 1;
    private int ident;

    /**
     * Max age timeout of the pool item
     */
    private long maxAgeTimeout = 0L;
    /**
     * Max open timeout of the pool item
     */
    private long maxOpenTimeout = 0L;
    /**
     * Start time of the pool item
     */
    private long startTime = 0L;

    /**
     * Creation time
     */
    private long creationTime;

    /**
     * Total connection time of the pool item
     */
    private long totalConnectionTime = 0L;

    /**
     * number of uses
     */
    private int uses = 0;

    /**
     * List of Thread infos of clients that opened this connection.
     */
    private List<Map<String, Object>> openerThreadInfos = new ArrayList<Map<String, Object>>();

    /**
     * List of Thread infos of clients that released this connection.
     */
    private List<Map<String, Object>> closerThreadInfos = new ArrayList<Map<String, Object>>();

    /**
     * Default Constructor
     */
    public PoolItemStats() {
        creationTime = System.currentTimeMillis();
        ident = objcount++;
    }

    /**
     * Get an Ident to be used for Administration
     * @return Ident
     */
    public int getIdent() {
        return ident;
    }

    /**
     * Get the max age timeout
     * @return long max age timeout
     */
    public long getMaxAgeTimeout() {
        return maxAgeTimeout;
    }

    /**
     * Set the max age timeout
     * @param pTime long max age timeout
     */
    public void setMaxAgeTimeout(final long pTime) {
        maxAgeTimeout = pTime;
    }

    /**
     * Get the max open timeout
     * @return long max open timeout
     */
    public long getMaxOpenTimeout() {
        return maxOpenTimeout;
    }

    /**
     * Set the max open timeout
     * @param pTime long max open timeout
     */
    public void setMaxOpenTimeout(final long pTime) {
        maxOpenTimeout = pTime;
    }

    /**
     * Get the creation time
     * @return creation time
     */
    public long getCreationTime() {
        return creationTime;
    }

    /**
     * Get the start time
     * @return long start time
     */
    public long getStartTime() {
        return startTime;
    }

    /**
     * Set the start time
     * @param pTime long start time
     */
    public void setStartTime(final long pTime) {
        startTime = pTime;
    }

    /**
     * Get the total connection time
     * @return long total connection time
     */
    public long getTotalConnectionTime() {
        return totalConnectionTime;
    }

    /**
     * Set the total connection time
     * @param pTime long total connection time
     */
    public void setTotalConnectionTime(final long pTime) {
        totalConnectionTime += pTime;
    }

    /**
     * Get the number of uses
     * @return int number of uses
     */
    public int getUses() {
        return uses;
    }

    /**
     * Increment the number of uses
     */
    public void incrementUses() {
        uses++;
    }

    /**
     * @return the list of stack traces of clients that have opened this connection.
     */
    public List<Map<String, Object>> getOpenerThreadInfos() {
        return openerThreadInfos;
    }

    /**
     * @return the list of stack traces of clients that have closed this connection.
     */
    public List<Map<String, Object>> getCloserThreadInfos() {
        return closerThreadInfos;
    }

    /**
     * Keep thread stack trace of opener
     */
    public void addOpenerThreadInfos() {
        openerThreadInfos.add(getThreadInfos());
    }

    /**
     * Keep thread stack trace of closer
     */
    public void addCloserThreadInfos() {
        closerThreadInfos.add(getThreadInfos());
    }

    /**
     * Compute Thread related informations.
     * @return a list containing: thread name, time of the action
     *         and a stack trace (as a string).
     */
    private Map<String, Object> getThreadInfos() {
        Map<String, Object> infos = new HashMap<String, Object>();
        // Name
        infos.put("thread.name", Thread.currentThread().getName());
        // Now
        infos.put("thread.time", new Long(System.currentTimeMillis()));
        // Stack trace (JDK 1.4 compatible)
        StringWriter str = new StringWriter();
        PrintWriter writer = new PrintWriter(str);
        new Throwable().printStackTrace(writer);
        infos.put("thread.stack", str.getBuffer().toString());

        return infos;
    }

    /**
     * String representing this object
     * @return String representing the object
     */
    @Override
    public String toString() {
       String out = "MaxAgeTimeout = " + maxAgeTimeout
                    + "\nMaxOpenTimeout = " + maxOpenTimeout
                    + "\nStartTime = " + startTime
                    + "\nTotalConnectionTime = " + totalConnectionTime
                    + "\nUses = " + uses;
       return out;
    }

}