/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

/*
 * CommonHandlers.java
 *
 */

package com.sun.enterprise.tools.admingui.handlers;

import java.io.IOException;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.StringTokenizer;
import java.util.Enumeration;

import com.iplanet.jato.RequestContext;
import com.iplanet.jato.RequestContextImpl;
import com.iplanet.jato.RequestManager;
import com.iplanet.jato.ViewBeanManager;
import com.iplanet.jato.model.DefaultModel;
import com.iplanet.jato.model.Model;
import com.iplanet.jato.util.RootCauseException;
import com.iplanet.jato.view.ContainerView;
import com.iplanet.jato.view.ContainerViewBase;
import com.iplanet.jato.view.View;
import com.iplanet.jato.view.DisplayFieldImpl;
import com.iplanet.jato.view.DisplayField;
import com.iplanet.jato.view.ViewBase;
import com.iplanet.jato.view.ViewBean;
import com.iplanet.jato.view.html.SelectableGroup;
import com.iplanet.jato.view.html.OptionList;
import com.iplanet.jato.view.event.RequestInvocationEvent;
import com.iplanet.jato.view.event.ViewRequestInvocationEvent;
import com.iplanet.jato.view.event.ViewCommandEvent;

import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.AttributeList;
import javax.management.Attribute;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
import com.sun.enterprise.tools.guiframework.model.ModelManager;
import com.sun.enterprise.tools.guiframework.view.DescriptorCCPageTitle;
import com.sun.enterprise.tools.guiframework.view.DescriptorCCTabs;
import com.sun.enterprise.tools.guiframework.view.DescriptorContainerView;
import com.sun.enterprise.tools.guiframework.view.HandlerContext;
import com.sun.enterprise.tools.guiframework.view.ViewDescriptorManager;
import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
import com.sun.enterprise.tools.guiframework.view.descriptors.CCActionTableDescriptor;
import com.sun.enterprise.tools.guiframework.view.event.BeforeCreateEvent;
import com.sun.enterprise.tools.guiframework.view.event.ErrorEvent;

import com.sun.web.ui.model.CCActionTableModelInterface;
import com.sun.web.ui.view.html.CCTextField;
import com.sun.web.ui.view.html.CCCheckBox;
import com.sun.web.ui.taglib.html.CCDropDownMenuTag;
import com.sun.web.ui.view.propertysheet.CCPropertySheet;
import com.sun.web.ui.view.tabs.CCTabs;

import com.sun.enterprise.tools.admingui.util.MBeanUtil;
import com.sun.enterprise.tools.admingui.util.Util;
import com.sun.enterprise.tools.admingui.tree.IndexTreeNode;
import com.sun.enterprise.tools.admingui.tree.IndexTreeModelImpl;
import com.sun.enterprise.tools.admingui.tree.IndexTreeModel;

import com.sun.enterprise.security.CipherInfo;


/**
 *
 */
public class SSLHandlers {

    
    public void displayCiphersValues(RequestContext ctx, HandlerContext handlerCtx) {
	View view = handlerCtx.getView();
        if (!(view instanceof DescriptorContainerView)) {
            View parent = view.getParent();
            if (!(parent instanceof DescriptorContainerView)) {
		throw new FrameworkException("View is not a DescriptorContainerView!", null, view);
            }  else {
                view = parent;
            }
        }
        if (view instanceof DescriptorCCPageTitle) {
            view = view.getParent();
        }
        DescriptorContainerView descView = (DescriptorContainerView)view;

        ArrayList cipherNames = (ArrayList)handlerCtx.getInputValue("cipherNames");
        if (cipherNames == null)
            throw new FrameworkException("cipherNames not specified", descView.getViewDescriptor(), view);
        
        String objectName = (String)handlerCtx.getInputValue("objectName");
        if (objectName == null)
            throw new FrameworkException("objectName not specified", descView.getViewDescriptor(), view);
        
        Object values = null;
        try {
            values = MBeanUtil.getMBeanServer().getAttributes(new ObjectName(objectName), 
                    (String[])cipherNames.toArray(new String[cipherNames.size()]));
        } catch (Exception ex) {
            throw new FrameworkException("displayCiphersValues: failed to get MBean values", 
                ex, descView.getViewDescriptor(), view);
        }

        AttributeList attrList = (AttributeList)values;
        boolean allNull = true;
        for (int i = 0; i < attrList.size(); i++) {
            Attribute attr = (Attribute)attrList.get(i);
            Object attrValue = attr.getValue();
            if (attrValue != null) allNull = false;
            parseAndSet(descView, attrValue);
        }
        if (allNull) {
            descView.setDisplayFieldValue("allSupported", "true");
        }
    }
    
    public void createSSL(RequestContext ctx, HandlerContext handlerCtx) {
	View view = handlerCtx.getView();
        if (!(view instanceof DescriptorContainerView)) {
            View parent = view.getParent();
            if (!(parent instanceof DescriptorContainerView)) {
		throw new FrameworkException("View is not a DescriptorContainerView!", null, view);
            }  else {
                view = parent;
            }
        }
        if (view instanceof DescriptorCCPageTitle) {
            view = view.getParent();
        }
        DescriptorContainerView descView = (DescriptorContainerView)view;
        
        String objectName = (String)handlerCtx.getInputValue("objectName");
        if (objectName == null)
            throw new FrameworkException("objectName not specified", descView.getViewDescriptor(), view);

        /* We should  not delete/create SSL based on whether security is enabled. refer to bug#6172174
        String securityEnabled = (String)descView.getDisplayFieldValue("securityEnabled"); //fix: hard coded value
        if (securityEnabled.equalsIgnoreCase("false")){
            // security not enabled, remove ssl if one exist.
            deleteSSL(objectName);
            return;
        }
         */
        
        //Remove SSL if cert nickname is not entered.
        String certNickName = (String)descView.getDisplayFieldValue("certificateNickName"); //fix: hard coded value
        if (Util.isEmpty(certNickName)){
            deleteSSL(objectName);
            return;
        }
        
        ArrayList displayNames = (ArrayList)handlerCtx.getInputValue("sslDisplayNames");
        if (displayNames == null)
            throw new FrameworkException("sslDisplayNames not specified", descView.getViewDescriptor(), view);
        
        ArrayList modelNames = (ArrayList)handlerCtx.getInputValue("sslAttributeNames");
        if (modelNames == null)
            throw new FrameworkException("sslModelNames not specified", descView.getViewDescriptor(), view);
        
        //ArrayList ssl2CiphersNames = (ArrayList)handlerCtx.getInputValue("ssl2CipherNames");
        //if (ssl2CiphersNames == null)
        //    throw new FrameworkException("ssl2CipherNames not specified", descView.getViewDescriptor(), view);
            
        ArrayList ssl3CiphersNames = (ArrayList)handlerCtx.getInputValue("ssl3CipherNames");
        if (ssl3CiphersNames == null)
            throw new FrameworkException("ssl3CipherNames not specified", descView.getViewDescriptor(), view);


        String methodName = (String)handlerCtx.getInputValue("methodName");
        if (methodName == null)
            throw new FrameworkException("methodName not specified", descView.getViewDescriptor(), view);
        AttributeList attrList = new AttributeList();
        Attribute attr;
        for (int i = 0; i < displayNames.size(); i++) {
            attr = new Attribute((String)modelNames.get(i),
                (String)descView.getDisplayFieldValue(((String)(displayNames.get(i)))));
            attrList.add(attr);
	    if (Util.isLoggableFINEST()) {
		Util.logFINEST(":::"+modelNames.get(i)+"="+
		    descView.getDisplayFieldValue((String)(displayNames.get(i))));
	    }
        }
        
        //String ciphers = makeCipherList(descView, ssl2CiphersNames);
        //if (ciphers.equals("") == false) {
        //    attr = new Attribute("ssl2-ciphers", ciphers);
	//    if (Util.isLoggableFINEST()) {
        //    	Util.logFINEST("ssl2_ciphers=" + ciphers);
	//    }
        //    attrList.add(attr);
        //}
        String allSupported = (String)((CCCheckBox)descView.getChild("allSupported")).getValue();
        if (allSupported.equals("false")) {
            String ciphers = makeCipherList(descView, ssl3CiphersNames);
            if (ciphers.equals("") == false) {
                attr = new Attribute("ssl3-tls-ciphers", ciphers);
                //util.logFINEST("ssl3_ciphers=" + ciphers);
                attrList.add(attr);
            }
        }
        // First delete the existing SSL, then create a new one.
        deleteSSL(objectName);
        Object returnValue = createSSL(objectName, methodName, attrList);

	if (Util.isLoggableFINER()) {
	    Util.logFINER("createSSLReturnValue: " + returnValue);
	}
    }

    private void parseAndSet(DescriptorContainerView view, Object attrValue) {
        if (attrValue == null) {
            return;
        }
        StringTokenizer st = new StringTokenizer(attrValue.toString(),",", false);
        while (st.hasMoreTokens()) {
            String cipher = st.nextToken();
            if (cipher.charAt(0) == '+') {
                CipherInfo ci = CipherInfo.getCipherInfo(cipher.substring(1));
                if (ci != null) {
                    view.setDisplayFieldValue(ci.getCipherName(), "true");
                }
            } else if (cipher.charAt(0) == '-') {
                CipherInfo ci = CipherInfo.getCipherInfo(cipher.substring(1));
                if (ci != null) {
                    view.setDisplayFieldValue(ci.getCipherName(), "false");
                }
            }
        }
    }
    
    private String makeCipherList(DescriptorContainerView descView, ArrayList names) {
        String ciphers = "";
        for (int i = 0; i < names.size(); i++) {
            String value = (String)descView.getDisplayFieldValue((String)(names.get(i)));
            if (value.equalsIgnoreCase("true")) {
                if (i != 0) ciphers += ",";
                ciphers += "+" + names.get(i);
            } else {
                if (i != 0) ciphers += ",";
                ciphers += "-" + names.get(i);
            }
        }
        return ciphers;
    }
    
    private Object deleteSSL(String objectName) {
        Object returnValue = null;
        try {
            returnValue = MBeanUtil.invoke(objectName, "getSsl", null, null);
        } catch (Exception ex) {
	    //throw new FrameworkException(
            //    "Exception while attempting to peform getSsl.", ex, null, null);
        }
        if (returnValue == null)
            return null;
        try {
            returnValue = MBeanUtil.invoke(objectName, "removeSsl", null, null);
        } catch (Exception ex) {
	    throw new FrameworkException(
		"Exception while attempting to peform deleteSsl.", ex, null, null);
        }
        return returnValue;
    }
    
    private Object createSSL(String objectName, String methodName, AttributeList attrList) {
        Object params[] = {attrList}; 
        String types[] = {"javax.management.AttributeList"};
        Object returnValue = null;
        try {
            returnValue = MBeanUtil.invoke(objectName, methodName, params, types);
        } catch (Exception ex) {
	    throw new FrameworkException(
		"Exception while attempting to peform create.", ex, null, null);
        }
        return returnValue;
    }
        
    
}
