/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 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.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.service.container;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

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

import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.webapp.jonasadmin.JonasAdminJmx;
import org.ow2.jonas.webapp.jonasadmin.JonasBaseAction;
import org.ow2.jonas.webapp.jonasadmin.WhereAreYou;
import org.ow2.jonas.webapp.jonasadmin.common.ModuleItem;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 * @author Michel-Ange ANTON
 * @author Adriana Danes
 */

public class EditEarAction extends JonasBaseAction {

//	--------------------------------------------------------- Public Methods
    /**
     * Used to initialize the name variable of a ModuleItem when we could not
     * identify the J2EEModule corresponding to a given URL which containes such
     * a module contained in a given ear.
     * This situation can arrive only with WebModules (in this case the MBeans and
     * their ObjectNames are created by CATALINA, not by JOnAS).
     */
    private static String NONAME = "";

    public ActionForward executeAction(ActionMapping pMapping, ActionForm pForm
            , HttpServletRequest pRequest, HttpServletResponse pResponse)
    throws IOException, ServletException {

        // Selected ear
        String sObjectName = pRequest.getParameter("select");

        ObjectName oObjectName = null;
        String domainName = null;
        String serverName = null;
        String appName = null;

        // Form used
        EarForm oForm = null;
        if (sObjectName != null) {
            String sPath = null;
            try {
                // Recreate ObjectName
                oObjectName = ObjectName.getInstance(sObjectName);
                domainName = oObjectName.getDomain();
                serverName = oObjectName.getKeyProperty("J2EEServer");
                appName = oObjectName.getKeyProperty("name");
                
                // check Objectname
                if (!JonasManagementRepr.isRegistered(oObjectName, serverName)) {
                    refreshServicesTree(pRequest);
                    return (pMapping.findForward("ActionListAppContainers"));
                }
                // Build a new form
                oForm = new EarForm();
                oForm.reset(pMapping, pRequest);
                m_Session.setAttribute("earForm", oForm);
                URL earUrl = (java.net.URL) JonasManagementRepr.getAttribute(oObjectName, "earUrl", serverName);
                sPath = earUrl.toString();
                //oForm.setPath(sPath);
                oForm.setFilename(JonasAdminJmx.extractFilename(sPath));
                //oForm.setObjectName(sObjectName);
                //oForm.setModuleName(appName);
            } catch (Throwable t) {
                addGlobalError(t);
                saveErrors(pRequest, m_Errors);
                return (pMapping.findForward("Global Error"));
            }
        } else {
            // Used last form in session
            oForm = (EarForm) m_Session.getAttribute("earForm");
        }

        // Force the node selected in tree
        m_WhereAreYou.selectNameNode(getTreeBranchName(DEPTH_SERVER) + WhereAreYou.NODE_SEPARATOR
                + "services" + WhereAreYou.NODE_SEPARATOR + "ear" + WhereAreYou.NODE_SEPARATOR
                + oForm.getFilename(), true);

        // Populate
        try {
            if (oObjectName != null) {
                oForm.setEarPath((URL) JonasManagementRepr.getAttribute(oObjectName, "earUrl", serverName));
                oForm.setXmlDeploymentDescriptor(getStringAttribute(oObjectName, "deploymentDescriptor"));

                // Get modules and construct ModuleItem list
                ModuleItem moduleItem = null;
                String[] modules = getStringArrayAttribute(oObjectName, "modules");
                ArrayList<ModuleItem> wars = new ArrayList<ModuleItem>();
                ArrayList<ModuleItem> ejbJars = new ArrayList<ModuleItem>();
                ArrayList<ModuleItem> rars = new ArrayList<ModuleItem>();
                for (int i = 0; i < modules.length; i++) {
                    String module = modules[i];
                    ObjectName moduleOn = ObjectName.getInstance(module);
                    if(JonasAdminJmx.isWebModule(moduleOn)) {
                        // Create ModuleItem for a WebModule
                        // TO DO warURL -> url
                        URL warURL = (URL) JonasManagementRepr.getAttribute(moduleOn, "warURL", serverName);
                        String path = warURL.getPath();
                        moduleItem = new ModuleItem(getPathContext(moduleOn)
                                , moduleOn.toString()
                                , path);
                        wars.add(moduleItem);
                    }
                    if(JonasAdminJmx.isEJBModule(moduleOn)) {
                        // Create ModuleItem for a EJBModule
                        URL url = (URL) JonasManagementRepr.getAttribute(moduleOn, "url", serverName);
                        String path = url.getPath();
                        moduleItem = new ModuleItem(moduleOn.getKeyProperty("name")
                                , moduleOn.toString()
                                , path);
                        ejbJars.add(moduleItem);
                    }
                    if(JonasAdminJmx.isResourceAdapterModule(moduleOn)) {
                        // Create ModuleItem for a ResourceAdapterModule
                        // TO DO fileName -> url
                        String fileName = null;
                        fileName = (String) JonasManagementRepr.getAttribute(moduleOn, "fileName", serverName);
                        // TO DO path = url.getPath()
                        String path = fileName;
                        moduleItem = new ModuleItem(moduleOn.getKeyProperty("name")
                                , moduleOn.toString()
                                , path);
                        rars.add(moduleItem);
                    }
                }
                oForm.setWars(wars);
                oForm.setEjbjars(ejbJars);
                oForm.setRars(rars);
            }
        } catch (Throwable t) {
            addGlobalError(t);
            saveErrors(pRequest, m_Errors);
            return (pMapping.findForward("Global Error"));
        }
        // Forward to the jsp.
        return (pMapping.findForward("Ear"));
    }

    /**
     * Construct an array of Strings having the same size as the webModuleObjectNames array,
     * where each String represents the pathContext part of the name key property of the
     * corresponding OBJECT_NAME (same index in the 2 arrays).
     * Note that the structure of the name key property of ObjectNames created by Catalina
     * for WebModules is:
     * //host/pathContext
     * @param webModuleObjectNames array of OBJECT_NAMES corresponding to WebModule MBeans
     * @return array of pathContexts
     */
    private String[] getPathContexts(String[] webModuleObjectNames) {
        int nbNames = webModuleObjectNames.length;
        String[] ret = new String[nbNames];
        for (int i = 0; i < nbNames; i++) {
            ObjectName oObjectName = null;
            try {
                oObjectName = ObjectName.getInstance(webModuleObjectNames[i]);
            } catch (MalformedObjectNameException e) {
                ret[i] = null;
            }
            String nameKeyProp = oObjectName.getKeyProperty("name");
            ret[i] = WebAppItem.extractLabelPathContext(
                    nameKeyProp
                    , m_WhereAreYou.getCurrentCatalinaDefaultHostName());
        }
        return ret;
    }
    /**
     * Construct a Strings representing the pathContext part of the name key property of the
     * corresponding ObjectName.
     * Note that the structure of the name key property of ObjectNames created by Catalina
     * for WebModules is:
     * //host/pathContext
     * @param webModuleOn ObjectName corresponding to WebModule MBeans
     * @return pathContext
     */
    private String getPathContext(ObjectName webModuleOn) {
        String ret = null;
        String nameKeyProp = webModuleOn.getKeyProperty("name");
        ret = WebAppItem.extractLabelPathContext(
                nameKeyProp
                , m_WhereAreYou.getCurrentCatalinaDefaultHostName());
        return ret;
    }
    /**
     * Look for the occurence of a String in arrayPathContext in the war URL.
     * If found (index > -1) we suppose that this is the name used to construct
     * the OBJECT_NAME of the MBean associated to the war.
     * @param warPath the URL of a war contained in the current ear
     * @param webModuleObjectNames array of WebModule MBean OBJECT_NAMEs which are
     * associated to wars contained in the current ear.
     * @return -1 if no association could be made, > -1 if an association was found
     */
    private int getWebModuleIndex(URL warPath, String[] webModuleObjectNames, String serverName) {
        // In Jetty, JSR77 is not fully compliant yet.
        // So, should return -1 as warURL is not in the MBean.
        // link to bug #303876
        if (m_WhereAreYou != null && m_WhereAreYou.isJettyServer()) {
            return -1;
        }
        int index = -1;
        for (int i = 0; i < webModuleObjectNames.length; i++) {
            ObjectName webModuleObjectName = null;
            try {
                webModuleObjectName = ObjectName.getInstance(webModuleObjectNames[i]);
            } catch (MalformedObjectNameException e) {
                return -1;
            }
            URL webModuleWarPath = (URL) JonasManagementRepr.getAttribute(webModuleObjectName, "warURL", serverName);
            if (warPath.equals(webModuleWarPath)) {
                index = i;
                break;
            }
        }
        return index;
    }
}
