/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2007 Bull S.A.S.
 * 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.1 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin.monitoring.graph.servlets.server;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.lib.util.Log;
import org.ow2.jonas.webapp.jonasadmin.WhereAreYou;
import org.ow2.jonas.webapp.jonasadmin.monitoring.graph.utils.GraphUtils;

import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

public class CurrentNumberOfEntityBeanServlet extends HttpServlet {

    /**
     *
     */
    private static final long serialVersionUID = -1041865079729162762L;
//  compare current value with a  total bean value that should be = CurrentNumberOfEntityBean + CurrentNumberOfMDB
//  + CurrentNumberOfEJB + CurrentNumberOfSBF + CurrentNumberOfSBL
    /**
     * Logger.
     */
    private static Logger logger = Log.getLogger(Log.JONAS_ADMIN_PREFIX);
    //data source
    private Long[] data;
    private int index = 0;
    //default number ofmeasures
    private static final int DEF_NUM_MESURE = 120;
    @SuppressWarnings("unused")
    private static final long DEF_EPSILON_VALUE = (long) 0.0000000000001;
    private long total = 0;
  //over his value, number of thread is critical
    private static Long MAX_MEASURE_EXPECTED_VALUE = new Long(100);


    /**
     * Respond to a GET request for the content produced by
     * this servlet.
     *
     * @param req The servlet request we are processing
     * @param res The servlet response we are producing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doGet(HttpServletRequest req, HttpServletResponse res)

    throws IOException, ServletException {
        if (data == null) {
            data = new Long[DEF_NUM_MESURE];
        }
        HttpSession oSession = req.getSession();
        WhereAreYou oWhere = (WhereAreYou) oSession.getAttribute(WhereAreYou.SESSION_NAME);
        String serverName = oWhere.getCurrentJonasServerName();
        ObjectName srvOn = (ObjectName) oSession.getAttribute("srvOn");
        res.setContentType("image/png");
        OutputStream out = res.getOutputStream();
        //GET THE DATA TO DISPLAY


        int currentInt = (Integer) (JonasManagementRepr.getAttribute(srvOn, "CurrentNumberOfEntityBean", serverName));
        Long current = new Long(currentInt).longValue();
        int totalInt = 0;
            totalInt = currentInt
            +
            (Integer) (JonasManagementRepr.getAttribute(srvOn, "CurrentNumberOfEJB", serverName))
            +
            (Integer) (JonasManagementRepr.getAttribute(srvOn, "CurrentNumberOfMDB", serverName))
            +
            (Integer) (JonasManagementRepr.getAttribute(srvOn, "CurrentNumberOfSBF", serverName))
            +
            (Integer) (JonasManagementRepr.getAttribute(srvOn, "CurrentNumberOfSBL", serverName));

            total = new Long(totalInt).longValue();
        if (index == data.length - 1) {
            for (int i = 0; i < data.length-1; i++) {
                data[i] = data[i + 1 ];
            }
            data[index] = current;
        } else {
            data[index] = current;
            index ++;
        }
        // search the max value in the data array:
        long yMax = data[0].longValue();
        for (int i = 1; i < index; i++) {
            yMax = Math.max(yMax, data[i].longValue());
            // looking for k and n where: k.10^n <= yMax < (k+1).10^n
        }
        long tmp = yMax;
        int n = 0;
        while ((tmp / 10) >= 1) {
            tmp = tmp / 10;
            n++;
        }
        long k = tmp % 10;
        // pow = 10^n
        int pow = 1;
        for (int i = 0; i < n; i++) {
            pow = pow * 10;
            // draw the range on the y axis:
        }
        // secondly, the current memory used:
        int xLength = GraphUtils.DEF_SPACE_BETWEEN_LINES * data.length + GraphUtils.GAUGE_TEXT_MAX_LENGTH ;        int width = GraphUtils.LEFT_MARGIN + xLength + GraphUtils.HORIZONTAL_SPACE + GraphUtils.GAUGE_WIDTH + GraphUtils.RIGHT_MARGIN;
        BufferedImage img = new BufferedImage(width, GraphUtils.HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics g = img.getGraphics();
//      TODO draw main graph here
        GraphUtils.drawGraph(g, k, xLength, width, pow , n, index, data, MAX_MEASURE_EXPECTED_VALUE, "EntityBeans count", "", 1);
        GraphUtils.drawCurrentUsedPerTotal(g, current, total, xLength, "EntityBeans count", "", true, 1);
        try {
            ImageIO.write(img, "png", out);
        } catch (IIOException iioe) {
            logger.log(BasicLevel.DEBUG, "Flushing problem", iioe);
        }
        out.close();
    }
}
