/*
 * 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;

// 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 DatabaseServlet 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 dsName = null;

	/*
	 * Remarque : il me semble que cette servlet est TOUJOURS appellée avec au moins
	 * un parametre - dsName. Par conséquant, dsName ne sera jamais null après
	 * l'exécution du code ci-dessous
	 * A CONFIRMER !!
	 */
	try {
	    for (Enumeration e = request.getParameterNames() ; e.hasMoreElements() ;) {
		String paramName = (String)e.nextElement();
		if (paramName.equals("dsName")) {
		    dsName = request.getParameter("dsName");
		} else if (paramName.equals("JDBCConnMaxAge")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCConnMaxAge", 
						     new Integer(request.getParameter("JDBCConnMaxAge")));
		} else if (paramName.equals("JDBCConnCheckLevel")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCConnCheckLevel", 
						     new Integer(request.getParameter("JDBCConnCheckLevel")));
		} else if (paramName.equals("JDBCTestStatement")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCTestStatement", 
						     new String(request.getParameter("JDBCTestStatement")));
		} else if (paramName.equals("JDBCMinConnPool")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCMinConnPool", 
						     new Integer(request.getParameter("JDBCMinConnPool")));
		} else if (paramName.equals("JDBCMaxConnPool")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCMaxConnPool", 
						     new Integer(request.getParameter("JDBCMaxConnPool")));
		} else if (paramName.equals("JDBCSleepTimeOut")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCSleepTimeOut", 
						     new Integer(request.getParameter("JDBCSleepTimeOut")));
		} else if (paramName.equals("JDBCDeadLockPool")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCDeadLockPool", 
						     new Integer(request.getParameter("JDBCDeadLockPool")));
		} else if (paramName.equals("JDBCLoopWaitPool")) {
		    JonasManagementRepr.setAttribute(JonasObjectName.datasource(request.getParameter("dsName")), 
						     "JDBCLoopWaitPool", 
						     new Integer(request.getParameter("JDBCLoopWaitPool")));
		}

	    }
	} catch (Exception e) {
	    alertException = Script.alert(e.getMessage());
	    context.put("alertException", alertException);
	} 

	// Normalement, TOUJOURS !!
        if (dsName != null) {
	    context.put("dsName", dsName);
	    // Get general information about the datasource
	    String datasourceType = null;
	    Integer currentNumberOfJDBCConnectionsOpen = null;
	    String info_error = "";
	    try {
		datasourceType = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "DataSourceType");
		currentNumberOfJDBCConnectionsOpen = (Integer)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "CurrentNumberOfJDBCConnectionOpen");		       
		context.put("datasourceType", datasourceType);
		context.put("currentNumberOfJDBCConnectionsOpen", currentNumberOfJDBCConnectionsOpen);
	    } 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);
	    // Get dependences
	    String dep_error = "";
	    try {
		Object[] param = { dsName };
		String[] signature = { "java.lang.String" };
		java.util.Set allDep = (java.util.Set)JonasManagementRepr.invoke(JonasObjectName.ejbService(), 
										"getDataSourceDependence", 
										param, 
										signature);
		Hashtable dependences = new Hashtable();
		if (allDep.isEmpty()) {
		    logger.log(BasicLevel.ERROR, "Try to get dependences. Empty dependences set"); 
		} else {
		    for (Iterator i = allDep.iterator(); i.hasNext() ;) {
			ObjectName current = (ObjectName)i.next();
			Dependence dep = new Dependence(current);
			dependences.put(dep.getEjbName(), dep);
			logger.log(BasicLevel.ERROR, "One dependece fond and put in the context");
		    }	
		}
		context.put("dependences", dependences);
	    } catch (ManagementException e) {
		dep_error = "Error while getting attribute:" + e.toString();
	    } catch (MalformedObjectNameException me) {
		dep_error = "Incompatible name:" + me.getMessage();
	    } 
	    context.put("dep_error", dep_error);
	    // Get configuration information about the datasource
	    String datasourceDescription = null;
	    String url = null;
	    String className = null;
	    String userName = null;
	    String password = null;
	    String datasourceFactory = null;
	    String datasourceXADataName = null;
	    Integer JDBCConnMaxAge = null;
	    Integer JDBCConnCheckLevel = null;
	    String JDBCTestStatement = null;
	    String JDBCMinConnPool = null;
	    String JDBCMaxConnPool = null;
	    String JDBCSleepTimeOut = null;
	    String JDBCDeadLockPool = null;
	    String JDBCLoopWaitPool = null;
	    String config_error = "";
	    try {
		datasourceDescription = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "DataSourceDescription");
		context.put("datasourceDescription", datasourceDescription);
		url = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "Url");
		context.put("url", url);
		className = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "ClassName");
		context.put("className", className);
		userName = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "UserName");
		context.put("userName", userName);
		password = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "Password");
		context.put("password", password);
		datasourceFactory = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "DataSourceFactory");
		context.put("datasourceFactory", datasourceFactory);
		datasourceXADataName = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "DataSourceXADataName");
		context.put("datasourceXADataName", datasourceXADataName);  
		JDBCConnMaxAge = (Integer)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCConnMaxAge");
		context.put("JDBCConnMaxAge", JDBCConnMaxAge);
		JDBCConnCheckLevel = (Integer)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCConnCheckLevel");
		context.put("JDBCConnCheckLevel", JDBCConnCheckLevel);
		JDBCTestStatement = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCTestStatement");
		context.put("JDBCTestStatement", JDBCTestStatement);
		JDBCMinConnPool = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCMinConnPool");
		if ( JDBCLoopWaitPool == null)
		    context.put("JDBCMinConnPool", "");
		else
		    context.put("JDBCMinConnPool", JDBCMinConnPool);
		JDBCMaxConnPool = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCMaxConnPool");
		if (JDBCMaxConnPool == null)
		    context.put("JDBCMaxConnPool", "");
		else
		    context.put("JDBCMaxConnPool", JDBCMaxConnPool);
		JDBCSleepTimeOut = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCSleepTimeOut");
		if (JDBCSleepTimeOut == null)
		    context.put("JDBCSleepTimeOut", "");
		else
		    context.put("JDBCSleepTimeOut", JDBCSleepTimeOut);
		JDBCDeadLockPool = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCDeadLockPool");
		if (JDBCDeadLockPool == null)
		    context.put("JDBCDeadLockPool", "");
		else
		    context.put("JDBCDeadLockPool", JDBCDeadLockPool);
		JDBCLoopWaitPool = (String)JonasManagementRepr.getAttribute(JonasObjectName.datasource(dsName), "JDBCLoopWaitPool");
		if (JDBCLoopWaitPool == null)
		    context.put("JDBCLoopWaitPool", "");
		else
		    context.put("JDBCLoopWaitPool", JDBCLoopWaitPool);
	    } catch (ManagementException e) {
		config_error = "Error while getting attribute:" + e.getMessage();
	    } catch (javax.management.MalformedObjectNameException e2) {
		config_error = "Incompatible name:" + e2.getMessage();
	    }
	    context.put("config_error", config_error);
	}

	Template template = null;
	try {
	    template = getTemplate("DATABASE.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;
    }

}
