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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.apache.struts.upload.FormFile;
import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.lib.management.javaee.J2eeObjectName;
import org.ow2.jonas.lib.util.JonasObjectName;
import org.ow2.jonas.webapp.jonasadmin.JonasAdminJmx;
import org.ow2.jonas.webapp.jonasadmin.JonasBaseAction;

public class CmiObjectAction extends JonasBaseAction {
    /**
     * Size of Buffer
     */
    private static final int BUFFER_SIZE = 1024;
     @SuppressWarnings("unchecked")
    @Override
        public ActionForward executeAction(final ActionMapping p_Mapping, final ActionForm p_Form, final HttpServletRequest p_Request, final HttpServletResponse p_Response) throws IOException, ServletException {
            String sDomainName = m_WhereAreYou.getCurrentDomainName();
            String serverName = m_WhereAreYou.getCurrentJonasServerName();
            String forwardName = "displayCmiObjectInfo";
            String objName = p_Request.getParameter("objName");
            if (objName == null) {
                objName = m_WhereAreYou.getVar("objName");
            }else {
                m_WhereAreYou.addVar("objName", objName);
            }
            CmiObjectForm oForm = (CmiObjectForm) p_Form;
            String action = oForm.getAction();
            //set Text style for html texts.
            p_Request.setAttribute("htmlTextStyleLbPolicy", "htmlTextLbPolicy");
            p_Request.setAttribute("htmlTextStyleLbStrategy", "htmlTextLbPolicy");
            p_Request.setAttribute("htmlTextStyleMinPoolSize", "htmlText");
            p_Request.setAttribute("htmlTextStyleMaxPoolSize", "htmlText");
            try {
                     ObjectName cmiOn = JonasObjectName.cmiServer(sDomainName, serverName);
                     if (JonasAdminJmx.hasMBeanName(cmiOn, serverName)) {
                     oForm.setName(objName);
                    // Set clusterList = (Set)JonasManagementRepr.invoke(cmiOn, "getClusterNames", null, null, serverName);
                     String[] signature = new String[5];
                     signature[0] = "java.lang.String";
                     String[] params = new String[5];
                     params[0] = objName;

                     if (action != null) {
                         if (action.equals("changeLBPolicy")) {
                             String[] parameters = {objName, oForm.getCurrentLBPolicySelect()};
                             String[] sign = {"java.lang.String", "java.lang.String"};
                             JonasManagementRepr.invoke(cmiOn, "setPolicyClassName", parameters, sign, serverName);
                             p_Request.setAttribute("htmlTextStyleLbPolicy", "htmlTextLbPolicyChanged");
                         }else if (action.equals("loadLBPolicy")) {
                             //change lbPolicy infos
                             sendFile(oForm, oForm.getNewLbPolicyClass(), "policy", cmiOn, p_Request);
                         }else if (action.equals("loadLBStrategy")) {
                             sendFile(oForm, oForm.getNewLbPolicyClass(), "strategy", cmiOn, p_Request);
                        }else if(action.equals("changeLBStrategy")){
                            String[] parameters = {objName, oForm.getCurrentLBStrategySelect()};
                            String[] sign = {"java.lang.String", "java.lang.String"};
                            JonasManagementRepr.invoke(cmiOn, "setStrategyClassName", parameters, sign, serverName);
                            p_Request.setAttribute("htmlTextStyleLbStrategy", "htmlTextLbPolicyChanged");
                        }
                     }
                     String[] parameters = {objName};
                     String[] sign = {"java.lang.String"};
                     oForm.setName(objName);
                     oForm.setServerRefs((List)JonasManagementRepr.invoke(cmiOn, "getServerRefs", parameters, sign, serverName));
                     String currentLB = (String)JonasManagementRepr.invoke(cmiOn, "getPolicyClassName", parameters, sign, serverName);
                     oForm.setCurrentLBPolicy(new LBAttribute(currentLB, getSimpleClassName(currentLB)));
                     currentLB = (String)JonasManagementRepr.invoke(cmiOn, "getStrategyClassName", parameters, sign, serverName);
                     oForm.setCurrentLBStrategy(new LBAttribute(currentLB,getSimpleClassName(currentLB)));
                     oForm.setMinPoolSize(((Integer)JonasManagementRepr.invoke(cmiOn, "getMinPoolSize", parameters, sign, serverName)).intValue());
                     oForm.setMaxPoolSize(((Integer)JonasManagementRepr.invoke(cmiOn, "getMaxPoolSize", parameters, sign, serverName)).intValue());
                     oForm.setItfName((String)JonasManagementRepr.invoke(cmiOn, "getItfName", parameters, sign, serverName));
                     oForm.setClusterName(((ClusterAttribute)m_Session.getAttribute("currentCmiCluster")).getName());
                     oForm.setAction(null);
                     }else {
//                    	cmi MBean is not registered
                         p_Request.setAttribute("newcmi", false);
                    }
            }catch (Throwable t) {
                addGlobalError(t);
                saveErrors(p_Request, m_Errors);
                return (p_Mapping.findForward("Global Error"));
            }
            // Forward to the jsp.
            return (p_Mapping.findForward(forwardName));
        }

         /** Sends a file to the cmi server instance.
         * @param p_form current form
         * @param file The file to send
         * @param remoteMethodName The remote method name to invoke.
         * @param cmiOn
         * @param request
         */
        private void sendFile(final CmiObjectForm p_form, final FormFile file, final String remoteAttributeName,
                 final ObjectName cmiOn, final HttpServletRequest request) {

            String serverName = m_WhereAreYou.getCurrentJonasServerName();
            // retrieve the file name
            String fileName = file.getFileName();

            // retrieve the content type
            String contentType = file.getContentType();

            // retrieve the file size
            String size = (file.getFileSize() + " bytes");


            // J2EE server MBean
            ObjectName j2eeServer = J2eeObjectName.J2EEServer(m_WhereAreYou.getCurrentDomainName(), serverName);

            // invoke method on the MBean
            String sentFile = null;
            InputStream inputStream = null;
            ByteArrayOutputStream baos = null;
            int len;
            try {
                inputStream = file.getInputStream();
                baos = new ByteArrayOutputStream();
                byte[] buf = new byte[BUFFER_SIZE];
                // Read bytes
                while ((len = inputStream.read(buf)) > 0) {
                    baos.write(buf, 0, len);
                }
                byte[] bytesOfFile = baos.toByteArray();
                Object[] param = new Object[] {p_form.getName(),bytesOfFile, fileName, remoteAttributeName};
                String[] signature = {"java.lang.String", "[B", "java.lang.String", "java.lang.String"};
                sentFile = (String) JonasManagementRepr.invoke(j2eeServer, "receiveFile", param, signature, serverName);
            } catch (Exception e) {
                addGlobalError(e);
                saveErrors(request, m_Errors);
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (baos != null) {
                        baos.close();
                    }
                } catch (Exception e) {
                    getServlet().log("Cannot close streams", e);
                }

            }
            //destroy temporary file.
            file.destroy();
         }

        /**
         * get simple class name from a full class name. e.g org.toto.Titi --> Titi
         * @param fullClassName
         * @return
         */
        private String getSimpleClassName(final String fullClassName) {
            // TODO Auto-generated method stub
            for (int i = fullClassName.length() - 1; i >= 0; i--) {
                if (String.valueOf(fullClassName.charAt(i)).equals(".")) {
                    return fullClassName.substring(i + 1, fullClassName.length());
                }
            }
            return fullClassName;
        }
}
