/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2009 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 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
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin.domain;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ow2.jonas.lib.management.extensions.manager.ManagementEntryPoint;
import org.ow2.jonas.lib.management.extensions.server.ServerItem;
import org.ow2.jonas.lib.management.javaee.J2eeObjectName;
import org.ow2.jonas.webapp.jonasadmin.JonasBaseAction;
import org.ow2.jonas.webapp.jonasadmin.common.BeanComparator;
/**
 * Display domain and cluster informations.
 * @author Adriana Danes
 */
public class EditDomainAction extends JonasBaseAction {

    /**
     * Compute info about this domain or cluster.
     * Populate the DomainForm.
     * Eventually call the domain.jsp for display
     */
    @Override
    public ActionForward executeAction(final ActionMapping p_Mapping, final ActionForm p_Form
            , final HttpServletRequest p_Request, final HttpServletResponse p_Response)
    throws IOException, ServletException {

        // request parameter version allows to choose between the flex and the jsp version

        try {
            // Force the node selected in tree
            m_WhereAreYou.selectNameNode("domain*domain", true);

            // current Form - DomainForm used for domain and cluster management
            DomainForm oForm = (DomainForm) p_Form;

            // TEST new management endpoint to get general info
            // -------------------------------------------------
            ManagementEntryPoint domMgmt = ManagementEntryPoint.getInstance();
            // current domain and server name as seen from the ManagementEntryPoint
            String domainNameMgmt = domMgmt.getDomainName();
            String serverNameMgmt = domMgmt.getServerName();

            // current domain name
            String domainName = m_WhereAreYou.getCurrentDomainName();
            // current server name
            String currentServerName = m_WhereAreYou.getCurrentJonasServerName();
            // current domain's ObjectName
            ObjectName domainOn = J2eeObjectName.J2EEDomain(domainName);

            // request parameter gives the managed resource name
            String selected = p_Request.getParameter("select");
            if (selected == null) {
                // By default we edit the domain page
                // -- this is necessary for example when creating a cluster in the
                // domain, at the end of the ApplyClusterAction we come back
                // into EditDomainAction
                // -- maybe this should be treated otherwise ?
                selected = domainName;
            }

            // currently managed resource name (domain or cluster name)
            String name = selected;
            m_Session.setAttribute("currentCluster", name);

            // Support mgmt context switch from a slave to the master
            // (to the administrator server)
            String adminServerName = m_WhereAreYou.getAdminJonasServerName();
            if (!adminServerName.equals(m_WhereAreYou.getCurrentJonasServerName())) {
                m_WhereAreYou.refreshServers(p_Request, domainName, adminServerName);
                refreshTree(p_Request);
            }

            // Support domain map changes (for example, a new server added to a cluster)
            // get 'mapChanged' session attribute
            boolean changeMap = getChangeMap();
            if (changeMap) {
                refreshTree(p_Request);
                m_WhereAreYou.setTreeToRefresh(true);
                m_Session.setAttribute("mapChanged", new Boolean(false));
            }

            // Check if this is a cluster or not
            boolean isCluster = false;
            if (!name.equals(domainName)) {
                isCluster = true;
            }
            oForm.setCluster(isCluster);

            // Domain or cluster type
            boolean cmiCluster = false;
            if (isCluster) {
                oForm.setType(oForm.typeCluster);
                String clusterType = domMgmt.getClusterType(name);
                oForm.setClusterType(clusterType);
                if ("CmiCluster".equals(clusterType)) {
                    cmiCluster = true;
                }
            } else {
                oForm.setType(oForm.typeDomain);
            }

            // set general properties on the Form
            oForm.setName(name);
            oForm.setDomainName(domainName);
            oForm.setCluster(isCluster);
            //oForm.setDescription(getStringAttribute(onDomain, "description"));
            oForm.setMasterName(adminServerName);
            oForm.setMasterON(J2eeObjectName.J2EEServer(domainName, adminServerName).toString());
            oForm.setMaster(domMgmt.isMaster());

            // get the servers list (server names in the managed domain or cluster)
            ArrayList al = new ArrayList();
            String[] servers = null;
            if (oForm.isMaster()) {
                servers = domMgmt.getServerNames(name);
            } else {
                servers = domMgmt.getServerNames();
            }

            // In the domain view, check if a new server detected in order to do refresh
            if ("Domain".equals(oForm.getType()) && oForm.isMaster()) {
                int nbServers = servers.length;
                Integer nbServersObj =  ((Integer) m_Session.getAttribute("nbServers"));
                if (nbServersObj == null) {
                    m_Session.setAttribute("nbServers", new Integer(nbServers));
                } else {
                    if (nbServers != nbServersObj.intValue()) {
                        // Add the new servers number to the session
                        m_Session.setAttribute("nbServers", new Integer(nbServers));
                        if (nbServers > nbServersObj.intValue()) {
                            // Servers number in the domain increased
                            refreshTree(p_Request);
                            m_WhereAreYou.setTreeToRefresh(true);
                        }
                    }
                }
            }

            // Construct the ServerItems list
            for (int i = 0; i < servers.length; i++) {
                String serverName = servers[i];
                ObjectName on = J2eeObjectName.J2EEServer(domainName, serverName);
                ServerItem it = null;
                if (!oForm.isMaster() && serverName.equals(currentServerName)) {
                    it = new ServerItem(on, "RUNNING", null);

                } else {
                    //String serverState = getAttribute(on, domainOn, "getServerState", adminServerName);
                    String serverState = domMgmt.getServerState(serverName);
                    //String clusterdName = getAttribute(on, domainOn, "getServerClusterdaemon", adminServerName);
                    String clusterdName = domMgmt.getServerClusterdaemon(serverName);
                    it = new ServerItem(on, serverState, clusterdName);
                }
                al.add(it);
            }
            Collections.sort(al, new BeanComparator(new String[] {"name"}));

            // Associate the ServerItems list to "listServers" request parameter
            p_Request.setAttribute("listServers", al);

            // Construct the clusters and cluster daemons list
            // -- Only for a domain management --
            if (oForm.isMaster() && !isCluster) {
                // get the clusters list
                ArrayList clustAl = new ArrayList();
                String[] clusters = domMgmt.getClusters();
                for (int i = 0; i < clusters.length; i++) {
                    ObjectName on = ObjectName.getInstance(clusters[i]);
                    String clusterName = on.getKeyProperty("name");
                    if (!domainName.equals(clusterName)) {
                        String clusterState = domMgmt.getClusterState(clusterName);
                        ServerItem it = new ServerItem(on, clusterState, null);
                        it.setName(clusterName);
                        clustAl.add(it);
                    }
                }
                Collections.sort(clustAl, new BeanComparator(new String[] {"name"}));
                p_Request.setAttribute("listClusters", clustAl);

                // get the cluster daemons list
                ArrayList clustDaemonAl = new ArrayList();
                String[] clusterDaemons = domMgmt.getclusterDaemons();
                for (int i = 0; i < clusterDaemons.length; i++) {
                    ObjectName on = ObjectName.getInstance(clusterDaemons[i]);
                    String clusterdaemonName = on.getKeyProperty("name");
                    String clusterdaemonState = domMgmt.getClusterdaemonState(clusterdaemonName);
                    ServerItem it = new ServerItem(on, clusterdaemonState, null);
                    it.setName(clusterdaemonName);
                    clustDaemonAl.add(it);
                }
                Collections.sort(clustDaemonAl, new BeanComparator(new String[] {"name"}));
                p_Request.setAttribute("listCdps", clustDaemonAl);// Re-check server states for a more accurate display
                //dm.refreshStates();
            } else {
                p_Request.setAttribute("listClusters", new ArrayList());
                p_Request.setAttribute("listCdps", new ArrayList());
            }
            if (cmiCluster) {
                // TODO latter
                return (p_Mapping.findForward("ClusterCMI"));
            }
        } catch (Throwable t) {
            addGlobalError(t);
            saveErrors(p_Request, m_Errors);
            return (p_Mapping.findForward("Global Error"));
        }
        // Forward to the jsp.
        return (p_Mapping.findForward("Domain"));

    }

    private boolean getChangeMap() {
        Boolean changeMapObj =  ((Boolean) m_Session.getAttribute("mapChanged"));
        if (changeMapObj == null) {
            return false;
        } else {
            return changeMapObj.booleanValue();
        }
    }

}
