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

/*
 * ConnectorConnectionPoolHandlers.java
 *
 * Created on November 26, 2003, 2:35 PM
 */

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

import java.util.Properties;
import java.util.ArrayList;
import java.util.Map;
import java.util.Vector;
import java.util.Iterator;
import java.util.Set;
import javax.management.ObjectName;
import javax.management.AttributeList;
import javax.management.Attribute;
import javax.management.j2ee.statistics.CountStatistic;
import javax.management.j2ee.statistics.TimeStatistic;


import com.iplanet.jato.RequestContext;
import com.iplanet.jato.RequestManager;
import com.iplanet.jato.view.View;
import com.iplanet.jato.view.ViewBase;
import com.sun.web.ui.model.CCActionTableModelInterface;
import com.iplanet.jato.view.ContainerView;
import com.iplanet.jato.view.ContainerViewBase;
import com.iplanet.jato.view.html.SelectableGroup;
import com.iplanet.jato.view.html.OptionList;
import com.iplanet.jato.model.DefaultModel;
import com.iplanet.jato.view.event.ChildContentDisplayEvent;
import com.sun.web.ui.model.CCActionTableModel;
import com.iplanet.jato.model.ModelControlException;
import com.iplanet.jato.view.html.*;
import com.iplanet.jato.util.NonSyncStringBuffer;

import com.sun.enterprise.tools.guiframework.view.event.BeforeCreateEvent;
import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
import com.sun.enterprise.tools.guiframework.view.DescriptorContainerView;
import com.sun.enterprise.tools.guiframework.view.DescriptorCCPageTitle;
import com.sun.enterprise.tools.guiframework.view.descriptors.CCActionTableDescriptor;
import com.sun.enterprise.tools.guiframework.view.HandlerContext;
import com.sun.enterprise.tools.guiframework.view.DescriptorCCActionTable;
import com.sun.enterprise.tools.admingui.util.MBeanUtil;
import com.sun.enterprise.tools.admingui.util.Util;
import com.sun.enterprise.tools.admingui.util.AMXUtil;
import com.sun.appserv.management.j2ee.statistics.StringStatistic;
import com.sun.appserv.management.helper.LBConfigHelper;

import com.sun.enterprise.deployment.phasing.ApplicationConfigHelper;
import com.sun.enterprise.deployment.phasing.DeploymentServiceUtils;

import com.sun.appserv.management.monitor.statistics.LoadBalancerServerStats;
import com.sun.appserv.management.monitor.statistics.LoadBalancerContextRootStats;
import com.sun.appserv.management.base.QueryMgr;
import com.sun.appserv.management.config.LBConfig;


/**
 *
 */
public class LoadBalancerHandlers {

    public void setLbProperties(RequestContext ctx, HandlerContext handlerCtx) {

        String objectName = (String) handlerCtx.getInputValue("objectName");
        String methodName = (String) handlerCtx.getInputValue("methodName");
        AttributeList properties = (AttributeList)handlerCtx.getInputValue("properties");
        if(properties == null){
            properties = new AttributeList();
        }
        Object[] params = null;
        String[] types = {"javax.management.Attribute"};

        for (int i = 0; i < properties.size(); i++) {
            Attribute attr = (Attribute)properties.get(i);
                try {
                    MBeanUtil.invoke(objectName, methodName, new Object[] {attr}, types);
                }catch (Exception  ex) {
                    
                    Util.logINFO("Could not set property for load balancer:"+ex.getMessage());
                    
                }            
        }
    }
    
    public void getLbProperties(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        String methodName = (String)handlerCtx.getInputValue("methodName");
        String propName = (String)handlerCtx.getInputValue("propName");
       String[] types = {"java.lang.String"};
        String propValue = "";
       try {
            propValue = (String)MBeanUtil.invoke(objectName, methodName, new Object[] {propName}, types);
        } catch (Exception ex) {
            // ignore no property value
        }
        
        handlerCtx.setOutputValue("value", propValue);
        
        
    }    
    
    public void getTargetList(RequestContext ctx, HandlerContext handlerCtx) {
        ObjectName[] clusterNames = (ObjectName[])handlerCtx.getInputValue("clusterRefs");
        ObjectName[] serverNames = (ObjectName[])handlerCtx.getInputValue("serverRefs");
        String[] targets = null;
        boolean serverList = false;
        boolean clusterList = false;
        if(serverNames != null && serverNames.length >0){
            serverList = true;
        }
        if(clusterNames != null && clusterNames.length >0){
            clusterList = true;
        }
        if(serverList && clusterList){
            targets = new String[clusterNames.length+serverNames.length];
            for (int i=0; clusterNames != null && i < clusterNames.length; i++) {
                targets[i] = clusterNames[i].getKeyProperty("ref");
            }
            
            
            for (int i=0; serverNames != null && i < serverNames.length; i++) {
                int start = clusterNames.length;
                targets[start+i] = serverNames[i].getKeyProperty("ref");
            }
            
        } else if(serverList && !clusterList){
            targets = new String[serverNames.length];
            for (int i=0; serverNames != null && i < serverNames.length; i++) {
                targets[i] = serverNames[i].getKeyProperty("ref");
            }
            
        } else if(!serverList && clusterList) {
            targets = new String[clusterNames.length];
            for (int i=0; clusterNames != null && i < clusterNames.length; i++) {
                targets[i] = clusterNames[i].getKeyProperty("ref");
            }
        }
      
	handlerCtx.setOutputValue("value", targets);
        if(targets != null){            
            handlerCtx.setOutputValue("hasValue", "true");
        }
            
    }        
   
    public void createLBReferences(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        String methodName = (String)handlerCtx.getInputValue("methodName");
        String key = (String)handlerCtx.getInputValue("key");
        String[] targets = (String[])handlerCtx.getInputValue("targets");
        String[] refs = (String[])handlerCtx.getInputValue("refs");
        if(targets != null){
            for(int i = 0; i < targets.length; i++){
                boolean foundMatch = false;
                if(refs != null){
                    for(int j = 0; j < refs.length; j++){
                        //boolean foundMatch = false;
                        if(targets[i].equals(refs[j])) {
                            foundMatch = true;
                        }
                    }
                    
                }
                if(!foundMatch || refs == null) {
                    if(isCluster(targets[i])) {
                        String[] types= new String[]{"javax.management.AttributeList"};
                        AttributeList attrList = new AttributeList();
                        attrList.add(new Attribute("ref", targets[i]));
                        Object params[] = {attrList};
                        MBeanUtil.invoke(objectName, "createClusterRef", params, types);
                    } else {
                        String[] types= new String[]{"javax.management.AttributeList"};
                        AttributeList attrList = new AttributeList();
                        attrList.add(new Attribute("ref", targets[i]));
                        Object params[] = {attrList};
                        MBeanUtil.invoke(objectName, "createServerRef", params, types);
                    }
                }
                
            }
        }
    }
    
    public void deleteLBReferences(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        String methodName = (String)handlerCtx.getInputValue("methodName");
        String key = (String)handlerCtx.getInputValue("key");
        String[] deleteTargets = (String[])handlerCtx.getInputValue("availableTargets");
        String[] types= new String[]{"java.lang.String"};
        
        if(deleteTargets != null) {
            for (int i = 0; i < deleteTargets.length; i++) {
                Object params[] = {deleteTargets[i]};
                if(isCluster(deleteTargets[i])){
                    
                    MBeanUtil.invoke(objectName, methodName, params, types);
                } else {
                    
                    MBeanUtil.invoke(objectName, "removeServerRefByRef", params, types);
                }
                
                
            }
        }
    }
    
   public void deleteClusterLBReferences(RequestContext ctx, HandlerContext handlerCtx) {
        String methodName = (String)handlerCtx.getInputValue("methodName");
        String cluster = (String)handlerCtx.getInputValue("cluster");
        String[] lbs = (String[])handlerCtx.getInputValue("lbs");
        String[] types= new String[]{"java.lang.String"};
        if(lbs == null)
            return;

        for (int i = 0; i < lbs.length; i++) {
            Object params[] = {cluster};
            try {
                MBeanUtil.invoke("com.sun.appserv:type=lb-config,name="+lbs[i]+",category=config", methodName, params, types);
            } catch (Exception ex) {
                throw new FrameworkException(
                "Error while deleting lb ref for   '"+cluster+
                "'!", ex, handlerCtx.getViewDescriptor(),
                handlerCtx.getView());
            }
        }
    }       
   
   public void createLoadBalancer(RequestContext ctx, HandlerContext handlerCtx) {
       String lbName = (String)handlerCtx.getInputValue("lbName");
       Object refName = (Object)handlerCtx.getInputValue("refs");
       String[] targets = {""};
       if (refName instanceof String) {
           String name = (String)refName;
           targets[0] = name;
       } else if(refName instanceof String[]) {
           targets = (String[])refName; 
       }
       
       try {
           Map params = null;
           LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
           helper.createLoadbalancer(lbName, true, targets, params);
       } catch (Exception ex) {
           if (Util.isLoggableFINE()) {
               Util.logFINE(ex);
           }
       }
   }

    private boolean isCluster(String name) {
        Object objName = null;
        
        String[] types= new String[]{"java.lang.String"};
        Object params[] = {name};
        try {
            objName = MBeanUtil.invoke("com.sun.appserv:type=clusters,category=config", "getClusterByName", params, types);
        } catch (Exception ex) {
            // ignore
        }
        if(objName != null) {
            return new Boolean("true").booleanValue();
        } else {
            return new Boolean("false").booleanValue();
        }
        
    }       
    
    public void isCluster(RequestContext ctx, HandlerContext handlerCtx) {
        String name = (String)handlerCtx.getInputValue("serverName");        
        Object objName = null;
        if (name != null ) {
                String[] types= new String[]{"java.lang.String"};
                Object params[] = {name};
                try {                
                    objName = MBeanUtil.invoke("com.sun.appserv:type=clusters,category=config", "getClusterByName", params, types);
                } catch (Exception ex) {
                    // ignore
                }                
                if(objName != null) {
                    handlerCtx.setOutputValue("isCluster", "true");
                } else {
                    handlerCtx.setOutputValue("isCluster", "false");
                }
                
           
        }
    }       
    
    public void getAttributeForClusterRef(RequestContext ctx, HandlerContext handlerCtx) {
        String[] targets = (String[])handlerCtx.getInputValue("targets");
        String cluster = (String)handlerCtx.getInputValue("clusterName");
        String attrName = (String)handlerCtx.getInputValue("attrName");
        String attrValue = "";
        if (targets != null && attrName != null){
            for (int i = 0; i < targets.length; i++) {
                attrValue = (String)MBeanUtil.getAttribute("com.sun.appserv:type=cluster-ref,ref="+cluster+",lb-config="+targets[i]+",category=config"
                , attrName);
            }
            
            handlerCtx.setOutputValue("attrValue", attrValue);
        }
    }  
    
    public void getAttributeForLB(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        String attrName = (String)handlerCtx.getInputValue("attrName");
        if (attrName==null)
            attrName="lb-config-name";
        Object value = null;
        value = MBeanUtil.getAttribute(objectName, attrName);
        String result = null;
        if (value != null) {
            if (value instanceof String) {
                result = (String)value;
            } else {
                result  = value.toString();
            }
        }        
        handlerCtx.setOutputValue("attrValue", result);
    

    }        
    
    public void setAttributeForLB(RequestContext ctx, HandlerContext handlerCtx) {
        String[] targets = (String[])handlerCtx.getInputValue("targets");
        String cluster = (String)handlerCtx.getInputValue("clusterName");
        String policy = (String)handlerCtx.getInputValue("policy");
        String module = (String)handlerCtx.getInputValue("module");
        if (targets != null && policy != null){
            for (int i = 0; i < targets.length; i++) {
                MBeanUtil.setAttribute("com.sun.appserv:type=cluster-ref,ref="+cluster+",lb-config="+targets[i]+",category=config"
                , new Attribute("lb-policy", policy));
                if(module != null){
                    MBeanUtil.setAttribute("com.sun.appserv:type=cluster-ref,ref="+cluster+",lb-config="+targets[i]+",category=config", new Attribute("lb-policy-module", module));
                    
                }
            }
            
            
        }
    }
    
    
    public void setAttribute(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        if (objectName == null) {
            throw new FrameworkException("LB Handler: setAttribute: Parameter 'objectName' not specified");
        }
        String propName = (String)handlerCtx.getInputValue("name");
        if (propName == null) {
            throw new FrameworkException("LB Handler: setAttribute: Parameter 'name' not specified");
        }
        String propValue = (String)handlerCtx.getInputValue("value");
        if (propValue == null) {
            throw new FrameworkException("LB Handler: setAttribute: Parameter 'value' not specified");
        }
        MBeanUtil.setAttribute(objectName, new Attribute(propName, propValue));
        
    }
    
    public void setConfigMonitoringEnabled(RequestContext ctx, HandlerContext handlerCtx) {
        String objectName = (String)handlerCtx.getInputValue("objectName");
        if (objectName == null) {
            throw new FrameworkException("LB Handler: setConfigMonitoringEnabled: Parameter 'objectName' not specified");
        }
        String propName = (String)handlerCtx.getInputValue("name");
        String propValue = (String)handlerCtx.getInputValue("value");
        if (propValue == null) {
            throw new FrameworkException("LB Handler: setConfigMonitoringEnabled: Parameter 'value' not specified");
        }
        
        Set<LBConfig>  lbConfigSet = null;
        QueryMgr queryMgr = AMXUtil.getQueryMgr();
        try {
            lbConfigSet = queryMgr.queryPatternSet(new ObjectName(objectName));
        } catch (javax.management.MalformedObjectNameException e) {
            e.printStackTrace();
        }
        for(LBConfig  lbconfig : lbConfigSet){
            //should be only 1.
            lbconfig.setMonitoringEnabled(new Boolean(propValue));
        }
    }
    
    
   public String endEditTabsDisplay(RequestContext ctx, HandlerContext handlerCtx) {
	if (!(handlerCtx.getEvent() instanceof ChildContentDisplayEvent)) {
	    return null;
	}
	ChildContentDisplayEvent dispEvent = (ChildContentDisplayEvent)handlerCtx.getEvent();
	String content = dispEvent.getContent();
        String key = (String)handlerCtx.getInputValue("key");
        String key2 = (String)handlerCtx.getInputValue("key2");
        if (key==null)
            key="editKeyValue";
        if (key2==null)
            key2="lbKey";        
        content = content.replaceAll(".PLACEHOLDER.", 
            "&"+ key + "=" + ctx.getRequest().getAttribute(key) +"&"+ key2 + "=" + ctx.getRequest().getAttribute(key2));
        return content;
    }    
   
   public void saveHealthChecker(RequestContext ctx, HandlerContext handlerCtx) throws ModelControlException {
       String lbConfigName = (String)handlerCtx.getInputValue("lbConfigName");
       if (lbConfigName == null) {
           throw new FrameworkException(
           "lbConfigName not specified in saveHealthChecker.");
       }
       
       String methodName = (String)handlerCtx.getInputValue("methodName");
       if (methodName == null) {
           methodName="createHealthChecker";
       }
       
       CCActionTableModelInterface model =
       (CCActionTableModelInterface)handlerCtx.getInputValue("lbTargetsModel");
       //((DefaultModel)model).clear();    
       //model.setRowSelectionType("multiple");
       
       if (model == null) {
           throw new FrameworkException("PropertiesHandler.getModel: Parameter 'propertiesModel' not specified");
       }
       //model.setRowSelectionType("multiple");
       model.beforeFirst();
       
       while(model.next()) {
           AttributeList attrs = new AttributeList();
           String name = null;
           Object objName = null;
           String interval = "";
           String timeout = "";
           String url = "";
           
           interval = (String) model.getValue("interval");
           timeout = (String) model.getValue("timeout");
           url = (String) model.getValue("url");
           name = (String)model.getValue("name");
           String[] type = new String[]{"javax.management.AttributeList"};
           
           
           if (!Util.isEmpty(interval)) {
               attrs.add(new Attribute("interval-in-seconds", interval));
               if(!Util.isEmpty(timeout))
                   attrs.add(new Attribute("timeout-in-seconds", timeout));
               if(!Util.isEmpty(interval))
                   attrs.add(new Attribute("url", url));
               if(!Util.isEmpty(name))
              
               if(!Util.isEmpty(url) && !Util.isEmpty(timeout)) {
                   String objectName = null;
                   String target = null;
                   if(isCluster(name)) {
                       objectName = "com.sun.appserv:type=cluster-ref,ref="+name+",lb-config="+lbConfigName+",category=config";
                       target = "cluster";
                       
                   } else {
                       objectName = "com.sun.appserv:type=server-ref,ref="+name+",lb-config="+lbConfigName+",category=config";                      
                       target = "server";
                       
                   }
                   Object[] params = new Object[]{attrs};

                   String objectName2 = "com.sun.appserv:type=health-checker,"+target+"-ref="+name+",lb-config="+lbConfigName+",category=config";
                   if (MBeanUtil.isValidMBean(objectName2)){
                       try {
                           MBeanUtil.setAttributes(objectName2, attrs);
                       } catch (Exception ex) {
                           throw new FrameworkException(
                           "Error while setting attributes on MBean '"+objectName+
                           "'!", ex, handlerCtx.getViewDescriptor(),
                           handlerCtx.getView());
                       }
                   } else {
                      MBeanUtil.invoke(objectName, methodName, params, type);
                   }
               }
           }
       }
   }
     
   
   public void saveInstanceWeight(RequestContext ctx, HandlerContext handlerCtx) throws ModelControlException {
       CCActionTableModelInterface model =
       (CCActionTableModelInterface)handlerCtx.getInputValue("lbTargetsModel");
       //((DefaultModel)model).clear();
       //model.setRowSelectionType("multiple");
       
       if (model == null) {
           throw new FrameworkException("PropertiesHandler.getModel: Parameter 'propertiesModel' not specified");
       }
       model.setRowSelectionType("multiple");
       
       model.beforeFirst();
       
       while(model.next()) {
           String weight = "";
           String name = "";
           name = (String) model.getValue("name");
           weight = (String) model.getValue("weight");
           Attribute attr = null;
           if(!Util.isEmpty(name) && !Util.isEmpty(weight)) {
               attr = new Attribute("lb-weight", weight);
               try {
                   MBeanUtil.setAttribute("com.sun.appserv:type=server,name="+name+",category=config", attr);
               } catch (Exception ex) {
                   throw new FrameworkException(
                   "Error while setting lb weight on  '"+name+
                   "'!", ex, handlerCtx.getViewDescriptor(),
                   handlerCtx.getView());
               }
           }
           
       }
   }

    
    public void getHealthChecker(RequestContext ctx, HandlerContext handlerCtx) throws ModelControlException {
       String lbConfigName = (String)handlerCtx.getInputValue("lbConfigName");
	if (lbConfigName == null) {
	    throw new FrameworkException(
                "lbConfigName not specified in saveHealthChecker.");
	}
        String[] targets = (String[])handlerCtx.getInputValue("targets");      
         CCActionTableModelInterface model =
            (CCActionTableModelInterface)handlerCtx.getInputValue("lbTargetsModel");

        if (model == null) {
            throw new FrameworkException("PropertiesHandler.getModel: Parameter 'propertiesModel' not specified");
        }
        //model.setRowSelectionType("multiple");
        String Interval = "";
        String Timeout = "";
        String URL = "";
        String name = null;

        ((DefaultModel)model).clear();
        model.beforeFirst();
        //model.setRowSelectionType("multiple");
        if (targets != null) {
            for (int i = 0; i < targets.length; i++) {
                model.appendRow();
                //((CCActionTableModel)model).sort();
                String target = null;
                if(isCluster(targets[i])) {
                    target = "cluster";
                } else {
                    target = "server";
                    
                }
                String objectName = "com.sun.appserv:type=health-checker,"+target+"-ref="+targets[i]+",lb-config="+lbConfigName+",category=config";
                try {
                    Interval = (String)MBeanUtil.getAttribute(objectName, "interval-in-seconds");
                    Timeout = (String)MBeanUtil.getAttribute(objectName, "timeout-in-seconds");
                    URL = (String)MBeanUtil.getAttribute(objectName, "url");
                    if(!isEmpty(URL))
                        model.setValue("url", URL);
                    if(!isEmpty(Timeout))
                        model.setValue("timeout", Timeout);
                    if(!isEmpty(Interval))
                        model.setValue("interval", Interval);
                } catch (Exception ex) {
                    // ignore no health checker created
                }
                if(!isEmpty(targets[i]))
                    model.setValue("name", targets[i]);
                
            }
        }
    }
    
    public void executeMethodOnInstance(RequestContext ctx, HandlerContext handlerCtx) {
        // Executes the given method on the selected rows of the table.
        //
	View view = handlerCtx.getView(); // this return the CCButton
	DescriptorContainerView descView = 
            (DescriptorContainerView)(((ViewBase)view).getParentViewBean());
	ViewDescriptor vd = descView.getViewDescriptor();
	String childName = (String)handlerCtx.getInputValue("tableChildName");
	String objectName = (String)handlerCtx.getInputValue("objectName");        
	if(childName == null) {
	    throw new FrameworkException("executeMethod: childName not specified", vd, view);
	}
        
	ViewDescriptor tableDescriptor = vd.getChildDescriptor(childName);
	if (tableDescriptor == null) {
	    throw new FrameworkException("executeMethod: tableDescriptor is null", vd, view);
	}
	if(!(tableDescriptor instanceof CCActionTableDescriptor)) {
	    throw new FrameworkException(
                "executeMethod: tableDescriptor is of wrong type", tableDescriptor, view);
	}
        CCActionTableModelInterface model = 
            ((CCActionTableDescriptor)tableDescriptor).getModel();
	String method = (String)handlerCtx.getInputValue("method");
        if (method == null) {
	    throw new FrameworkException("executeMethod: method name is null", vd, view);
        }
        
	model.setRowSelectionType("multiple");
        //String objectName = null;
        String[] types = {"java.lang.String"};
	try {
	    model.beforeFirst();
	    while(model.next()) {
		if (model.isRowSelected()) {
                    if(objectName == null)
                        objectName = (String)model.getValue("objectName");
                    if (objectName == null) 
                        continue; // should be an error.
                    String instanceName = (String) model.getValue("name");
                    MBeanUtil.invoke(objectName, method, new Object[] {instanceName}, types);
		    model.setRowSelected(false);
                }
            }
	} catch (Exception ex) {
	    throw new FrameworkException("Error while invoking '" + method +
                "' on " + objectName, ex, tableDescriptor, view);
        }
	ContainerViewBase containerView = 
            (ContainerViewBase)(tableDescriptor.getView(ctx).getParent());
	containerView.removeChild(tableDescriptor.getName());
	((DefaultModel)model).clear();
    }    
    
    public void getInstancesforQuiesce(RequestContext ctx, HandlerContext handlerCtx) {
        // Executes the given method on the selected rows of the table.
        //
	View view = handlerCtx.getView(); // this return the CCButton
	DescriptorContainerView descView = 
            (DescriptorContainerView)(((ViewBase)view).getParentViewBean());
	ViewDescriptor vd = descView.getViewDescriptor();
	String childName = (String)handlerCtx.getInputValue("tableChildName");
	if(childName == null) {
	    throw new FrameworkException("executeMethod: childName not specified", vd, view);
	}
        
	ViewDescriptor tableDescriptor = vd.getChildDescriptor(childName);
	if (tableDescriptor == null) {
	    throw new FrameworkException("executeMethod: tableDescriptor is null", vd, view);
	}
	if(!(tableDescriptor instanceof CCActionTableDescriptor)) {
	    throw new FrameworkException(
                "executeMethod: tableDescriptor is of wrong type", tableDescriptor, view);
	}
        CCActionTableModelInterface model = 
            ((CCActionTableDescriptor)tableDescriptor).getModel();
       
	model.setRowSelectionType("multiple");
	try {
	    model.beforeFirst();
            String instances = "";
	    while(model.next()) {
                if (model.isRowSelected()) {
                    if(instances.equals("")) {
                        instances += (String) model.getValue("name");
                        
                    } else {
                        instances += "@"+(String) model.getValue("name");
                    }
                    model.setRowSelected(false);
                }
            }
            handlerCtx.setOutputValue("value", instances);
	} catch (Exception ex) {
	    throw new FrameworkException("setQuiescevalues: error getting instance names from table");
        }
	ContainerViewBase containerView = 
            (ContainerViewBase)(tableDescriptor.getView(ctx).getParent());
	containerView.removeChild(tableDescriptor.getName());
	((DefaultModel)model).clear();
    }        
    
    public void getLB(RequestContext ctx, HandlerContext handlerCtx) {
        String[] targets = (String[])handlerCtx.getInputValue("targets");
        ObjectName[] lbs = (ObjectName[])handlerCtx.getInputValue("lbs");
        String key = (String)handlerCtx.getInputValue("key");
        if(key == null)
            key = "name";
        
        if (targets != null && lbs != null) {
            for (int i = 0; i < targets.length; i++) {
                String lbConfig = "";
                String name = "";
                for(int j = 0; j < lbs.length; j++){
                    lbConfig = (String)MBeanUtil.getAttribute(lbs[j].toString(), "lb-config-name");
                    if(targets[i].equals(lbConfig)) {
                        name = lbs[j].getKeyProperty("name");
                    }
                    if(!name.equals("")){
                        handlerCtx.setOutputValue("value", name);
                        return;
                    }
                }
                
            }
        }
    }  
    
    public void beginQuiesce(RequestContext ctx, HandlerContext handlerCtx) {        
        String instances = (String)handlerCtx.getInputValue("instances");
        String lbName = (String)handlerCtx.getInputValue("lbName");
        String cluster = (String)handlerCtx.getInputValue("clusterName");
        String lbConfig = (String)handlerCtx.getInputValue("lbConfig");
        String[] targets = null;
        if (Util.isEmpty(instances)){
            //this shouldn't happen. meaning nothing passed in.
        }else{
            targets = instances.split("@");
            
        }        
        if(targets != null) {
            for(int i = 0; i< targets.length; i++){
                if(cluster != null) {
                    MBeanUtil.setAttribute("com.sun.appserv:type=server-ref,ref="+targets[i]+",cluster="+cluster+",category=config", new Attribute("lb-enabled", false));
                    
                } else {
                    MBeanUtil.setAttribute("com.sun.appserv:type=server-ref,ref="+targets[i]+",lb-config="+lbConfig+",category=config", new Attribute("lb-enabled", false));
                     
                }
            }
        }
            
    }      
    
    public void stopInstances(RequestContext ctx, HandlerContext handlerCtx) {
        String instances = (String)handlerCtx.getInputValue("instances");
        String[] targets = null;
        if (Util.isEmpty(instances)){
            //this shouldn't happen. meaning nothing passed in.
        }else{
            targets = instances.split("@");
        }
        try {
            
            if(targets != null) {
                for(int i = 0; i< targets.length; i++){
                    Boolean isRunning = null;
                    isRunning = (Boolean)MBeanUtil.invoke("com.sun.appserv:type=server,name="+targets[i]+",category=config", "isRunning", null, null);
                   if(isRunning.booleanValue()){
                        MBeanUtil.invoke("com.sun.appserv:type=server,name="+targets[i]+",category=config", "stop", null, null);
                    }
                    
                }
            }
        } catch (Exception ex) {
            throw new FrameworkException("Stop Instances: Error while stopping instances", ex, handlerCtx.getViewDescriptor(),
                   handlerCtx.getView());
        }
        
        
    }
    
    // add a hidden variable for the highlight ID and include javascript
    /*public String endExtraInstancesDisplay(RequestContext ctx, HandlerContext handlerCtx) {
        ChildContentDisplayEvent ev = (ChildContentDisplayEvent)handlerCtx.getEvent();
	View bean = handlerCtx.getView();

	while (!(bean instanceof DescriptorContainerView)) {
	    // Should only happen once, if at all.
	    bean = bean.getParent();
	}
        // remember the current view (page) so we can go back to it when switching trees.
        setCurrentView(ctx, bean);

        NonSyncStringBuffer buff = new NonSyncStringBuffer(ev.getContent(), 512);
        
        String script = (String)handlerCtx.getInputValue("script") ;
        if (script != null) {
            buff.append("\n").append(script);
	}

        
        buff.append("\n<input name=\"instances\" type=\"hidden\" value=\"")
            .append("instance1").append("\">");
        
        return buff.toString();
    }*/
    
    public String endDisplayLBTargetsInTable(RequestContext ctx, HandlerContext handlerCtx) {
	if (!(handlerCtx.getEvent() instanceof ChildContentDisplayEvent)) {
	    return null;
	}
	ChildContentDisplayEvent dispEvent = (ChildContentDisplayEvent)handlerCtx.getEvent();
	String content = dispEvent.getContent();
        String[] targets = (String[])handlerCtx.getInputValue("targets");
        String key = (String)handlerCtx.getInputValue("key");
        if(key == null)
            key = "name";
        
        String hrefs = "";
        if (targets != null) {
            for (int i = 0; i < targets.length; i++) {
                if (i > 0)
                    hrefs += "<br />";
                
                //String objectType = targets[i].getKeyProperty("type");
                boolean isCluster = isCluster(targets[i]);  
                String target = null;
                if(isCluster){
                    target = "cluster";
                } else {
                    target = "serverInstance";
                }


                String tmp = content.replaceFirst(".TARGETVALUE.", 
                    targets[i]+"&nextPage="+target);
                hrefs += tmp.replaceAll(".TARGETVALUE.", 
                    targets[i]);
            }
        }
        return hrefs;
    }    
    
    public String endDisplayInstanceStatus(RequestContext ctx, HandlerContext handlerCtx) {
        if (!(handlerCtx.getEvent() instanceof ChildContentDisplayEvent)) {
            return null;
        }
        ChildContentDisplayEvent dispEvent = (ChildContentDisplayEvent)handlerCtx.getEvent();
        String content = dispEvent.getContent();
        String instances = (String)handlerCtx.getInputValue("instances");
        String lbName = (String)handlerCtx.getInputValue("lbName");
        
        String text = "";
        String[] targets = null;
        if (Util.isEmpty(instances)){
            //this shouldn't happen. meaning nothing passed in.
        }else{
            //instances passed in will be in the form of name1@name2@name3, need to seperate it out
            targets = instances.split("@");
            
            //the following line can be commented out when API is checked in.
            //still have to figure out how to present the chart for more than 1 instance case.
            //Map lbServerMonitorMap = LBConfigHelper.getInstanceAggregateStats(String names[0]) ;
        }
        if (targets != null && lbName != null) {
            for (int i = 0; i < targets.length; i++) {
                if (i > 0)
                    text += "<br />";
                
                String[] types= new String[]{"java.lang.String"};
                Object params[] = {targets[i]};
                String status = null;
                try {

                    status = (String)MBeanUtil.invoke("amx:j2eeType=X-LoadBalancer,name="+lbName, "getStatus", params, types);
                } catch (Exception ex) {
                   throw new FrameworkException("Error while getting instance: '"+lbName, ex, handlerCtx.getViewDescriptor(),
                   handlerCtx.getView());
                }
                
                
                
                String tmp = content.replaceFirst(".TARGETVALUE.",
                targets[i]+": "+status);
                text += tmp.replaceAll(".TARGETVALUE.",
                targets[i]+": "+status);
            }
        }
        
        return text;
    }    
    
    public String endDisplayQuiesceTimeout(RequestContext ctx, HandlerContext handlerCtx) {
        if (!(handlerCtx.getEvent() instanceof ChildContentDisplayEvent)) {
            return null;
        }
        ChildContentDisplayEvent dispEvent = (ChildContentDisplayEvent)handlerCtx.getEvent();
        String content = dispEvent.getContent();
        String instances = (String)handlerCtx.getInputValue("instances");
        String cluster = (String)handlerCtx.getInputValue("cluster");
        String lbConfig = (String)handlerCtx.getInputValue("lbConfig");        
        String text = "";
        String [] targets = null;
        if (Util.isEmpty(instances)){
            return "";
        }else{
            targets = instances.split("@");
        }
        
        if(targets != null) {
            for(int i = 0; i< targets.length; i++){
                if (i > 0)
                    text += "<br />";
                String timeout = null;
                
                try {
                    if(cluster != null) {
                        timeout = (String)MBeanUtil.getAttribute("com.sun.appserv:type=server-ref,ref="+targets[i]+",cluster="+cluster+",category=config", "disable-timeout-in-minutes");
                        
                    } else {
                        timeout = (String)MBeanUtil.getAttribute("com.sun.appserv:type=server-ref,ref="+targets[i]+",lb-config="+lbConfig+",category=config", "disable-timeout-in-minutes");
                        
                    }
                } catch (Exception ex) {
                    throw new FrameworkException("Error while getting quiesce timeout: '"+targets[i], ex, handlerCtx.getViewDescriptor(),
                    handlerCtx.getView());
                }
                String tmp = content.replaceFirst(".TARGETVALUE.",
                targets[i]+": "+timeout);
                text += tmp.replaceAll(".TARGETVALUE.",
                targets[i]+": "+timeout);
                
            }
            
        }
        return text;
    } 
    
    public void populateLbFilterMenu(RequestContext ctx, HandlerContext handlerCtx) {
        // the child should be something like: com.sun.web.ui.view.html.CCDropDownMenu
        String lbName = (String)handlerCtx.getInputValue("lbName");        
	if(lbName == null) {
	    throw new FrameworkException("populateFilterMenu: lbName not specified");
	}     
        SelectableGroup dropDownChild = (SelectableGroup) handlerCtx.getView();
        OptionList optionList = new OptionList();
        LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
        String[] targets = helper.listTargets(lbName);
        if (targets == null)
            return; 
        OptionList dropDownMenuOptions = new OptionList(targets, targets); // label and values
        dropDownChild.setOptions(dropDownMenuOptions);     
        if (targets.length > 0) {
            dropDownChild.setValue(targets[0]);
        }        
    }    
    
   public void listTargets(RequestContext ctx, HandlerContext handlerCtx) {
        // the child should be something like: com.sun.web.ui.view.html.CCDropDownMenu
        String lbName = (String)handlerCtx.getInputValue("lbName");        
	if(lbName == null) {
	    throw new FrameworkException("listTargets: lbName not specified");
	}     
        LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
        String[] targets = helper.listTargets(lbName);
        if (targets == null){
            return; 
        }
        for(int i = 0; i < targets.length; i++){
        }
        handlerCtx.setOutputValue("value", targets);
        handlerCtx.setOutputValue("hasValue", "true");
     
    }        
   
    
    public void populateLbAppsFilterMenu(RequestContext ctx, HandlerContext handlerCtx) {
        // the child should be something like: com.sun.web.ui.view.html.CCDropDownMenu
        String lbName = (String)handlerCtx.getInputValue("lbName");
        String target = (String)handlerCtx.getInputValue("target");
        if(lbName == null) {
            throw new FrameworkException("populateFilterAppsMenu: lbName not specified");
        }
        if(target == null) {
            return;
        }
        SelectableGroup dropDownChild = (SelectableGroup) handlerCtx.getView();
        OptionList optionList = new OptionList();
        //context root is hard-coded-we are waiting for api(Harsha) to get context root         
        String[] targets = null;
        boolean isCluster = true;
        try {
            targets = (String[])MBeanUtil.invoke("com.sun.appserv:type=cluster,name="+target+",category=config", "listApplicationReferencesAsString", null, null);
        } catch (Exception ex) {
            // ignore
            isCluster = false;
        }
        if(!isCluster) {
            try {
                targets = (String[])MBeanUtil.invoke("com.sun.appserv:type=server,name="+target+",category=config", "listApplicationReferencesAsString", null, null);
            } catch (Exception ex) {
                // ignore
                isCluster = true;
            }
        }
        Vector ctxRootList = new Vector();        
        for(int i = 0; i < targets.length; i++){
            String[] ctxRoot = null;
            try {
                ctxRoot = ApplicationConfigHelper.getAppContextRoots(DeploymentServiceUtils.getConfigContext(),targets[i]);
            } catch (Exception ex) {
               throw new FrameworkException(
                           "Error while getting context roots for '"+targets[i]+
                           "'!", ex, handlerCtx.getViewDescriptor(),
                           handlerCtx.getView());
            }     
            if(ctxRoot != null){
                for(int j = 0; j < ctxRoot.length; j++){
                    ctxRootList.add(ctxRoot[j]);
                }
            }
            
        }
        String[] ctxroot = (String[])ctxRootList.toArray(new String[ctxRootList.size()]);
        OptionList dropDownMenuOptions = new OptionList(ctxroot, ctxroot); // label and values
        dropDownChild.setOptions(dropDownMenuOptions);
        if (ctxroot.length > 0) {
            dropDownChild.setValue(ctxroot[0]);
        }           
    }
    
    
    public void loadInstanceStats(RequestContext ctx, HandlerContext handlerCtx){
        View view = handlerCtx.getView();
        ViewDescriptor desc = null;
        if (handlerCtx.getEvent() instanceof BeforeCreateEvent) {
            desc = ((BeforeCreateEvent)handlerCtx.getEvent()).getViewDescriptor();
        } else {
            DescriptorContainerView descView = (DescriptorContainerView)
            (((ViewBase)view).getParentViewBean());
            desc = descView.getViewDescriptor();
        }
        String lbName = (String)handlerCtx.getInputValue("lbName");
        if(lbName == null)  {
            throw new FrameworkException("populateFilterMenu: lbName not specified");
        }
        String target = (String)handlerCtx.getInputValue("target");
        boolean allTargets = false;
        if(target == null) {
            allTargets = true;
        }
        CCActionTableModelInterface model =(CCActionTableModelInterface)handlerCtx.getInputValue("model");
        if (model == null) {
            throw new FrameworkException("loadInstanceStats: No Model Specified.",
            desc, handlerCtx.getView());
        }
        try {
            LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
            Map  stats = helper.getInstanceStats(lbName, target, allTargets);
            if(stats == null)
                return;
            Set s = stats.keySet();
            Iterator iter = s.iterator();
           ((DefaultModel)model).clear();
            model.beforeFirst();
            //model.setRowSelectionType("multiple");  
            while (iter.hasNext()) {
                Object key = iter.next();
                LoadBalancerServerStats oneRow = (LoadBalancerServerStats)stats.get(key);
                StringStatistic health = (StringStatistic)oneRow.getHealth();
                CountStatistic aReqs = (CountStatistic)oneRow.getNumberOfActiveRequests();
                CountStatistic tReqs = (CountStatistic)oneRow.getNumberOfActiveRequests();
                model.appendRow();
                model.setValue("target", key);
                model.setValue("health", health.getCurrent());
                model.setValue("activeReqs", aReqs.getCount());
                model.setValue("totalReqs", tReqs.getCount());
            }
        } catch (Exception ex) {
            // ignore
            return;
        }
        
    } 
    
    public void loadAppStats(RequestContext ctx, HandlerContext handlerCtx){
        View view = handlerCtx.getView();
        ViewDescriptor desc = null;
        if (handlerCtx.getEvent() instanceof BeforeCreateEvent) {
            desc = ((BeforeCreateEvent)handlerCtx.getEvent()).getViewDescriptor();
        } else {
            DescriptorContainerView descView = (DescriptorContainerView)
            (((ViewBase)view).getParentViewBean());
            desc = descView.getViewDescriptor();
        }
        
        String lbName = (String)handlerCtx.getInputValue("lbName");
        String contextRoot = (String)handlerCtx.getInputValue("contextRoot");
        if(contextRoot != null && contextRoot.startsWith("/")) {
            String converted = contextRoot.substring(1, contextRoot.length());
            contextRoot = converted;
        }        
        if(lbName == null)  {
            throw new FrameworkException("loadAppStats: lbName not specified");
        }
        String target = (String)handlerCtx.getInputValue("target");
        boolean allTargets = false;
        if(target == null) {
            allTargets = true;
        }
        CCActionTableModelInterface model =(CCActionTableModelInterface)handlerCtx.getInputValue("model");
        if (model == null) {
            throw new FrameworkException("loadAppStats: No Model Specified.",
            desc, handlerCtx.getView());
        }
        try {
            LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
            Map  stats = helper.getInstanceStats(lbName, contextRoot, target, allTargets);
            if(stats == null)
                return;
            Set s = stats.keySet();
            Iterator iter = s.iterator();
            ((DefaultModel)model).clear();
            model.beforeFirst();
            //model.setRowSelectionType("multiple");
            while (iter.hasNext()) {
                Object key = iter.next();
                LoadBalancerContextRootStats oneRow = (LoadBalancerContextRootStats)stats.get(key);
                TimeStatistic respTime = (TimeStatistic)oneRow.getResponseTime();
                CountStatistic avgRes = (CountStatistic)oneRow.getAverageResponseTime();
                CountStatistic failOvers = (CountStatistic)oneRow.getFailoverReqCount();
                CountStatistic errorPage = (CountStatistic)oneRow.getErrorRequestCount();
                CountStatistic url = (CountStatistic)oneRow.getIdempotentUrlAccessCount();
                CountStatistic activeReqs = (CountStatistic)oneRow.getActiveRequestCount();
                CountStatistic totalReqs = (CountStatistic)oneRow.getTotalRequestCount();
                model.appendRow();
                model.setValue("target", key);
                model.setValue("avgResponse", avgRes.getCount());
                model.setValue("failovers", failOvers.getCount());
                model.setValue("errorPage", errorPage.getCount());
                model.setValue("url", url.getCount());
                model.setValue("activeReqs", activeReqs.getCount());
                model.setValue("totalReqs", totalReqs.getCount());
                model.setValue("maxResponse", respTime.getMaxTime());
                model.setValue("minResponse", respTime.getMaxTime());
                //model.setValue(PROPERTY_VALUE, properties.get(key));
            }
        } catch (Exception ex) {
            // ignore
            return;
        }
        
        
    }
    
    public void deleteLoadBalancer(RequestContext ctx, HandlerContext handlerCtx) {
        View view = handlerCtx.getView();
        DescriptorContainerView descView = (DescriptorContainerView)(((ViewBase)view).getParentViewBean());
        ViewDescriptor vd = descView.getViewDescriptor();
        String childName = (String)handlerCtx.getInputValue("tableChildName");
        if(childName == null) {
            throw new FrameworkException("deleteHandler: childName not specified", vd, view);
        }
        
        ViewDescriptor tableDescriptor = vd.getChildDescriptor(childName);
        if (tableDescriptor == null) {
            throw new FrameworkException("deleteHandler: tableDescriptor is null", vd, view);
        }
        if(!(tableDescriptor instanceof CCActionTableDescriptor)) {
            throw new FrameworkException("deleteHandler: tableDescriptor is of wrong type", tableDescriptor, view);
        }
        CCActionTableModelInterface model = ((CCActionTableDescriptor)tableDescriptor).getModel();
        
        String deleteKey = (String)handlerCtx.getInputValue("deleteKey");
        
        if (deleteKey == null) {
            throw new FrameworkException("No delete key specified", tableDescriptor, view);
        }
        model.setRowSelectionType("multiple");
        try {
            model.beforeFirst();
            // from the model, get the child that has the needed value...
            while(model.next()) {
                if (model.isRowSelected()) {
                    LBConfigHelper helper = new LBConfigHelper(AMXUtil.getDomainRoot());
                    helper.removeLoadbalancer(model.getValue(deleteKey).toString());
                    model.setRowSelected(false);
                }
            }
            ContainerViewBase containerView =
            (ContainerViewBase)(tableDescriptor.getView(ctx).getParent());
            containerView.removeChild(tableDescriptor.getName());
            ((DefaultModel)model).clear();
        } catch (Exception ex) {
            throw new FrameworkException("Error while deleting from: '"+
            tableDescriptor.getName()+"'", ex, tableDescriptor, view);
        }

    }
    
            
    
        
    private static boolean isEmpty(String test) {
        return ((test == null) || "".equals(test));
    }
    
}
