package org.ow2.jonas.lib.management.extensions.clusterdaemon;

import java.util.ArrayList;
import java.util.List;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.ow2.jonas.lib.management.extensions.base.BaseManagement;
import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.lib.management.extensions.base.ManagementException;
import org.ow2.jonas.lib.util.JonasObjectName;
import org.ow2.jonas.management.extensions.clusterdaemon.api.IClusterdaemon;

/**
 * Implements clusterdaemon management functions.
 * @author Adriana Danes
 * @author Oualaa Hani
 */
    public class ClusterdaemonManagement extends BaseManagement implements IClusterdaemon {

        /* ======================= ClusterDaemonProxy MBean attributes ==================== */
        /* ======================= domainName:type=ClusterDaemonProxy,name=clusterdaemonName ==================== */
        private final static String state = "State";
        private final static String controlledServersNames = "ControlledServersNames";
        private final static String runningState = "RUNNING";

        /**
         * Constructor.
         */
        public ClusterdaemonManagement() {
        }

        /**
         * Get the ClusterDaemonProxy MBean ObjectName for a given cluster daemon.
         * @param clusterdaemonName the name of the cluster daemon
         * @return ClusterDaemonProxy MBean ObjectName
         */
        private ObjectName getClusterdaemonOn(final String clusterdaemonName) {
            String domain = getDomainName();
            ObjectName clusterdaemonOn = null;
            try {
                clusterdaemonOn = JonasObjectName.clusterDaemonProxy(domain, clusterdaemonName);
            } catch (MalformedObjectNameException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return clusterdaemonOn;
        }

        /**
         * @return the state of a cluster daemon in the domain
         * @param clusterdaemonName name of the cluster daemon to manage
         */
        public String getClusterdaemonState(final String clusterdaemonName) {
            ObjectName clusterdaemonOn = getClusterdaemonOn(clusterdaemonName);
            String clusterdaemonState = null;
            try {
                clusterdaemonState = (String) JonasManagementRepr.getAttribute(clusterdaemonOn, state, getServerName());
            } catch (ManagementException e) {
                logger.debug("Cannot get state for cluster daemon " + clusterdaemonName + " :" + e);
            }
            return clusterdaemonState;
        }

        /**
         * @param clusterdaemonName name of the cluster daemon to manage.
         * @return true if the cluster daemon is in RUNNING state, false otherwise
         */
        public boolean isRunning(final String clusterdaemonName) {
            boolean result = false;
            ObjectName clusterdaemonOn = getClusterdaemonOn(clusterdaemonName);
            try {
                String clusterdaemonState = (String) JonasManagementRepr.getAttribute(clusterdaemonOn, state, getServerName());
                if (runningState.equals(clusterdaemonState)) {
                    result = true;
                }
            } catch (ManagementException e) {
                logger.debug("Cannot get state for cluster daemon " + clusterdaemonName + " :" + e);
            }
            return result;
        }

        /**
         * @param clusterdaemonName name of the cluster daemon to manage
         * @return list of servers controlled by a clusterdaemon
         */
        public String[] getControlledServersNames(final String clusterdaemonName) {
            ObjectName clusterdaemonOn = getClusterdaemonOn(clusterdaemonName);
            List<String> servers = new ArrayList<String>();
            try {
                servers = (ArrayList<String>) JonasManagementRepr.getAttribute(clusterdaemonOn, controlledServersNames, getServerName());
                if (servers == null) {
                    return new String[0];
                }
            } catch (ManagementException e) {
                logger.debug("Cannot get controlled server names for cluster daemon " + clusterdaemonName + " :" + e);
                return null;
            }
            String[] controlledServers = new String [servers.size()];
            for (int i = 0; i < servers.size(); i++) {
                controlledServers[i] = servers.get(i);
            }
            return controlledServers;
        }

        /**
         * Start a server controlled by a cluster daemon. Use already defined start parameters and configuration.
         * @param clusterdaemonName name of the cluster daemon
         * @param serverName name of the server to start
         * @return true if successfully started
         */
        public boolean startServer(final String clusterdaemonName, final String serverName) {
            ObjectName clusterdaemonOn = getClusterdaemonOn(clusterdaemonName);
            Boolean result = null;
            String opName = "startServer";
            String[] opParams = new String[2];
            String[] opSignature = {"java.lang.String", "java.lang.String"};
            /** first parameter : server name */
            opParams[0] = serverName;
            /** second parameter : extra start parameters */
            opParams[1] = null;
            try {
                result = (Boolean) JonasManagementRepr.invoke(clusterdaemonOn, opName, opParams, opSignature, getServerName());
            } catch (ManagementException e) {
                logger.debug("Cannot start server " + serverName + " by cluster daemon " + clusterdaemonName + " :" + e);
                return false;
            }
            return result.booleanValue();
        }

        /**
         * Stop a server controlled by a cluster daemon.
         * @param clusterdaemonName name of the cluster daemon
         * @param serverName name of the server to stop
         * @return true if successfully stoped
         */
        public boolean stopServer(final String clusterdaemonName, final String serverName) {
            ObjectName clusterdaemonOn = getClusterdaemonOn(clusterdaemonName);
            Boolean result = null;
            String opName = "stopServer";
            String[] opParams = new String[2];
            String[] opSignature = {"java.lang.String", "java.lang.String"};
            /** first parameter : server name */
            opParams[0] = serverName;
            /** second parameter : extra start parameters */
            opParams[1] = null;
            try {
                result = (Boolean) JonasManagementRepr.invoke(clusterdaemonOn, opName, opParams, opSignature, getServerName());
            } catch (ManagementException e) {
                logger.debug("Cannot stop server " + serverName + " by cluster daemon " + clusterdaemonName + " :" + e);
                return false;
            }
            return result.booleanValue();
        }
    }
