/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.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 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
 *
 * Initial developer(s): ____________________________________.
 * Contributor(s): ______________________________________.
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.jmx.vjadmin.servlet;

// servlet imports
import javax.servlet.*;
import javax.servlet.http.*;

// standard imports
import java.util.Date;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

// velocity imports
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.servlet.VelocityServlet;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;

// JOnAS JMX imports
import org.objectweb.jonas.jmx.*;
// JMX
import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;

// Jadmin imports
import org.objectweb.jonas.jmx.vjadmin.*;

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

// JOnAS log imports
import org.objectweb.jonas.common.Log;

public class ContainerServlet extends VelocityServlet {
    static private Logger logger = null;

    public void init(ServletConfig config ) throws ServletException {
	super.init(config);
	logger = Log.getLogger(ServletLog.JONAS_VELO_SERVLET_PREFIX);
    }

    protected Context createContext( HttpServletRequest request, HttpServletResponse response) { 
	HttpSession session = request.getSession();
	// Try to get the initial VelocityContext
	VelocityContext initialContext = (VelocityContext)session.getAttribute("initialContext");
	if (initialContext == null) {
	    // initial context lost, recreate it
	    initialContext = InitVeloContext.doIt(session);
	    logger.log(BasicLevel.DEBUG, "Initial VelocityContext lost. Create, initialize and attach to the session a new initial VelocityContext");
	}
	VelocityContext context = new VelocityContext(initialContext);
	logger.log(BasicLevel.DEBUG, "Create a new VelocityContext containing the initial one");
	return context;
    } 
   
    /**
     *
     *
     *  @param ctx a Velocity Context object to be filled with
     *             data.  Will be used for rendering this 
     *             template
     *  @return Template to be used for request
     */   

    public Template handleRequest( HttpServletRequest request, 
				   HttpServletResponse response, 
				   Context context ) { 
	// Exception treatement
	String alertException = null;

 	// Get Date
	String date = java.text.DateFormat.getInstance().format(new Date());
	context.put("date", date);

	// Get request parameters
	String fileNameParam = null;

	try {
	    for (Enumeration e = request.getParameterNames() ; e.hasMoreElements() ;) {
		String paramName = (String)e.nextElement();
		if (paramName.equals("fileName")) {
		    fileNameParam = request.getParameter("fileName");
		}
	    }
	} catch (Exception e) {
	    alertException = Script.alert(e.getMessage());
	    context.put("alertException", alertException);
	}
	context.put("fileNameParam", fileNameParam.replace(' ', '+'));

	boolean containerSelected = true;
	if (fileNameParam != null) {
	    // Get general information about the container
	    logger.log(BasicLevel.DEBUG, "Container loaded from file " + fileNameParam);
	    String info_error = "";
	    ObjectName jmxContName = null;
	    String containerName = null;
	    String fileName = null;
	    Integer currentNumberOfBeanType = null;
	    try {
		jmxContName = JonasObjectName.container(fileNameParam);
		containerName = (String)JonasManagementRepr.getAttribute(jmxContName, "ContainerName");
		logger.log(BasicLevel.DEBUG, "- container name : " + containerName);
		fileName = (String)JonasManagementRepr.getAttribute(jmxContName, "FileName");
		logger.log(BasicLevel.DEBUG, "- file name : " + fileName);
		currentNumberOfBeanType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfBeanType");	
		context.put("containerName", containerName);
		context.put("fileName", fileName);
		context.put("currentNumberOfBeanType", currentNumberOfBeanType);
	    } catch (ManagementException e1) {
		info_error = "Error while getting attribute: " + e1.getMessage();
	    } catch (javax.management.MalformedObjectNameException e2) {
		info_error = "Incompatible name:" + e2.getMessage();		
	    }
	    context.put("info_error", info_error);

	    // Display Beans in this container:
	    String beans_error = "";
	    Integer currentNumberOfBMPType = null;
	    Integer currentNumberOfCMPType = null;
	    Integer currentNumberOfSBFType = null;
	    Integer currentNumberOfSBLType = null;
	    Integer currentNumberOfMDBType = null;
	    ObjectName pattern = null;
	    try {
		// BMP EJBs
		currentNumberOfBMPType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfBMPType");		
		context.put("currentNumberOfBMPType", currentNumberOfBMPType); 
		pattern = JonasObjectName.allEjbBmp(fileName);
		Set allBMP = (Set)JonasManagementRepr.queryNames(pattern);
		Vector allBMPNames = new Vector();
		if (!allBMP.isEmpty()) {
		    for (Iterator i = allBMP.iterator() ; i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			String beanName = (String)JonasManagementRepr.getAttribute(current, "EJBName");
			allBMPNames.add(beanName.replace(' ', '+'));
			logger.log(BasicLevel.DEBUG, "- BMP : " + beanName);
		    }
		}
		context.put("allBMPNames", allBMPNames);

		// CMP EJBs
		currentNumberOfCMPType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfCMPType"); 
		pattern = JonasObjectName.allEjbCmp(fileName);
		context.put("currentNumberOfCMPType", currentNumberOfCMPType);
		Set allCMP = (Set)JonasManagementRepr.queryNames(pattern);
		Vector allCMPNames = new Vector();
		if (!allCMP.isEmpty()) {
		    for (Iterator i = allCMP.iterator() ; i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			String beanName = (String)JonasManagementRepr.getAttribute(current, "EJBName");
			allCMPNames.add(beanName.replace(' ', '+'));
			logger.log(BasicLevel.DEBUG, "- CMP : " + beanName);
		    }
		}
		context.put("allCMPNames", allCMPNames);

		// Stateful SB
		currentNumberOfSBFType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfSBFType"); 
		context.put("currentNumberOfSBFType", currentNumberOfSBFType);
		pattern = JonasObjectName.allEjbSbf(fileName);
		Set allSBF = (Set)JonasManagementRepr.queryNames(pattern);
		Vector allSBFNames = new Vector();
		if (!allSBF.isEmpty()) {
		    for (Iterator i = allSBF.iterator() ; i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			String beanName = (String)JonasManagementRepr.getAttribute(current, "EJBName");
			allSBFNames.add(beanName.replace(' ', '+'));
			logger.log(BasicLevel.DEBUG, "- SBF : " + beanName);
		    }
		}
		context.put("allSBFNames", allSBFNames);

		//Steless SB
		currentNumberOfSBLType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfSBLType");
		context.put("currentNumberOfSBLType", currentNumberOfSBLType);
		pattern = JonasObjectName.allEjbSbl(fileName);
		Set allSBL = (Set)JonasManagementRepr.queryNames(pattern);
		Vector allSBLNames = new Vector();
		if (!allSBL.isEmpty()) {
		    for (Iterator i = allSBL.iterator() ; i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			String beanName = (String)JonasManagementRepr.getAttribute(current, "EJBName");
			allSBLNames.add(beanName.replace(' ', '+'));
			logger.log(BasicLevel.DEBUG, "- SBL : " + beanName);
		    }
		}
		context.put("allSBLNames", allSBLNames);

		// MDB EJBs
		currentNumberOfMDBType = (Integer)JonasManagementRepr.getAttribute(jmxContName, "CurrentNumberOfMDBType");
		pattern = JonasObjectName.allEjbMdb(fileName);
		Set allMDB = (Set)JonasManagementRepr.queryNames(pattern);
		Vector allMDBNames = new Vector();
		if (!allMDB.isEmpty()) {
		    for (Iterator i = allMDB.iterator() ; i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			String beanName = (String)JonasManagementRepr.getAttribute(current, "EJBName");
			allMDBNames.add(beanName.replace(' ', '+'));
			logger.log(BasicLevel.DEBUG, "- MDB : " + beanName);
		    }
		}
		context.put("currentNumberOfMDBType", currentNumberOfMDBType);
		context.put("allMDBNames", allMDBNames);
	    } catch (ManagementException e) {
		beans_error = "Error while getting attribute:" + e.toString();
	    } 
	    context.put("beans_error", beans_error);
	} else {
	    containerSelected = false;
	}
	context.put("containerSelected", new Boolean(containerSelected));

	Template template = null;
	try {
	    template = getTemplate("CONTAINER.vm"); 
	} catch (ParseErrorException pee ) {
            logger.log(BasicLevel.ERROR, "Parse error for template " + pee);
        } catch( ResourceNotFoundException rnfe) {
            logger.log(BasicLevel.ERROR, "Template not found " + rnfe);
        } catch( Exception e) {
            logger.log(BasicLevel.ERROR, "Error " + e);
        }

	return template;
    }

}
