/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2011 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 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.cluster.daemon.rest.impl;

import org.ow2.jonas.cluster.daemon.api.ClusterDaemonException;
import org.ow2.jonas.cluster.daemon.rest.api.Attribute;
import org.ow2.jonas.cluster.daemon.rest.api.IClusterDaemon;
import org.ow2.jonas.cluster.daemon.rest.api.ServerName;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public class ClusterDaemon implements IClusterDaemon {

    private org.ow2.jonas.cluster.daemon.api.IClusterDaemon clusterDaemon;

    private Log logger = LogFactory.getLog(this.getClass());


    public ClusterDaemon(org.ow2.jonas.cluster.daemon.api.IClusterDaemon clusterDaemon) {
        this.clusterDaemon = clusterDaemon;
    }

    public String getObjectName() throws ClusterDaemonException {
        logger.debug("Retrieving object name.");
        return clusterDaemon.getObjectName();
    }

    public void setObjectName(String name) throws ClusterDaemonException {
        logger.debug("Setting object name = '" + name + "'");
        clusterDaemon.setObjectName(name);
    }

    public String isEventProvider() throws ClusterDaemonException {
        logger.debug("Querying if this is an event provider.");
        String result = String.valueOf(clusterDaemon.iseventProvider());
        return result;
    }

    public String isStateManageable() throws ClusterDaemonException {
        logger.debug("Querying if this is event manageable.");
        String result = String.valueOf(clusterDaemon.isstateManageable());
        return result;
    }

    public String isStatisticsProvider() throws ClusterDaemonException {
        logger.debug("Querying if this is a statistics provider.");
        String result = String.valueOf(clusterDaemon.isstatisticsProvider());
        return result;
    }

    public List<ServerName> serversNames() throws ClusterDaemonException {
        logger.debug("Retrieving servers' names.");

        ArrayList results = clusterDaemon.serversNames();
        List<ServerName> entries = new ArrayList<ServerName>();
        for(Object name : results) {
            entries.add(new ServerName((String) name));
        }
        return entries;
    }

    public String getDomain4Server(String name) throws ClusterDaemonException {
        logger.debug("Retrieving domain name for '" + name + "'.");
        return clusterDaemon.getDomain4Server(name);
    }

    public String getJavaHome4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving $JAVA_HOME for '" + name + "'.");
        return clusterDaemon.getJavaHome4Server(name);
    }

    public String getJonasRoot4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving $JONAS_ROOT for '" + name + "'.");
        return clusterDaemon.getJonasRoot4Server(name);
    }

    public String getJonasBase4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving $JONAS_BASE for '" + name + "'.");
        return clusterDaemon.getJonasBase4Server(name);
    }

    public String getJonasCmd4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving JOnAS commands for '" + name + "'.");
        return clusterDaemon.getJonasCmd4Server(name);
    }

    public String getXprm4Server(String name) throws ClusterDaemonException {
        logger.debug("Retrieving extra parameters for '" + name + "'.");
        return clusterDaemon.getXprm4Server(name);
    }

    public String getAutoBoot4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving autoboot mark for '" + name + "'.");
        return clusterDaemon.getAutoBoot4Server(name);
    }

    public String getJmxPort4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving JMX port for '" + name + "'.");
        return clusterDaemon.getJmxPort4Server(name);
    }

    public String getJmxUrl4Server(String name)
            throws ClusterDaemonException {

        logger.debug("Retrieving JMX url for '" + name + "'.");
        return clusterDaemon.getJmxUrl4Server(name);
    }

    public void reloadConfiguration() throws ClusterDaemonException {
        logger.debug("Reloading configuration...");
        clusterDaemon.reloadConfiguration();
    }

    public void addServer(String name, String domain, String description, String jonasRoot,
                          String jonasBase, String javaHome, String xprm,
                          String autoBoot, String jmxPort, String jonasCmd)
            throws ClusterDaemonException {
        logger.debug("Adding a new server named '" + name + "'.");
        logger.debug("  Description: '" + description + "'.");
        logger.debug("  $JONAS_ROOT = '" + jonasRoot + "'");
        logger.debug("  $JONAS_BASE = '" + jonasBase + "'");
        logger.debug("  $JAVA_HOME = '" + javaHome + "'");
        logger.debug("  Extra parameters: '" + xprm + "'");
        logger.debug("  Auto boot: '" + autoBoot + "'");
        logger.debug("  JMX port: '" + jmxPort + "'");
        logger.debug("  JOnAS Commands: '" + jonasCmd + "'");
        clusterDaemon.addServer(name, domain, description, jonasRoot, jonasBase,
                javaHome, xprm, autoBoot, jmxPort, jonasCmd, "true");
    }

    public void modifyServer(String name, String domain, String description, String javaHome,
                             String jonasRoot, String jonasBase, String xprm,
                             String autoBoot, String jmxPort, String jonasCmd)
            throws ClusterDaemonException {
        clusterDaemon.modifyServer(name, domain, description, javaHome, jonasRoot,
                jonasBase, xprm, autoBoot, jmxPort, jonasCmd);
    }

    public void removeServer( String serverName)
            throws ClusterDaemonException {
        clusterDaemon.removeServer(serverName, "true");
    }

    public void saveConfiguration() throws ClusterDaemonException {
        clusterDaemon.saveConfiguration();
    }

    public void startJOnAS(String name, String prm)
            throws ClusterDaemonException {
        clusterDaemon.startJOnAS(name, prm);
    }

    public void stopJOnAS(String name) throws ClusterDaemonException {
        clusterDaemon.stopJOnAS(name);
    }

    public void haltJOnAS(String name) throws ClusterDaemonException {
        clusterDaemon.haltJOnAS(name);
    }

    public String pingJOnAS(String name) throws ClusterDaemonException {
        return String.valueOf(clusterDaemon.pingJOnAS(name));
    }

    public String startAllJOnAS(String prm, String domainName)
            throws ClusterDaemonException {
        return clusterDaemon.startAllJOnAS(domainName, prm);
    }

    public String stopAllJOnAS() throws ClusterDaemonException {
        return clusterDaemon.stopAllJOnAS();
    }

    public void stopClusterDaemon() throws ClusterDaemonException {
        clusterDaemon.stopClusterDaemon();
    }

    public String getJmxUrl() throws ClusterDaemonException {
        return clusterDaemon.getJmxUrl();
    }

    public String getOperatingSystemAvailableProcessors()
            throws ClusterDaemonException {
        return clusterDaemon.getOperatingSystemAvailableProcessors();
    }

    public String getOperatingSystemName() throws ClusterDaemonException {
        return clusterDaemon.getOperatingSystemName();
    }

    public String getOperatingSystemArch() throws ClusterDaemonException {
        return clusterDaemon.getOperatingSystemArch();
    }

    public String getOperatingSystemVersion() throws ClusterDaemonException {
        return clusterDaemon.getOperatingSystemVersion();
    }

    public String getRunTimeSpecVendor() throws ClusterDaemonException {
        return clusterDaemon.getRunTimeSpecVendor();
    }

    public String getRunTimeSpecVersion() throws ClusterDaemonException {
        return clusterDaemon.getRunTimeSpecVersion();
    }

    public String getRunTimeVmName() throws ClusterDaemonException {
        return clusterDaemon.getRunTimeVmName();
    }

    public String getRunTimeVmVendor() throws ClusterDaemonException {
        return clusterDaemon.getRunTimeVmVendor();
    }

    public String getRunTimeVmVersion() throws ClusterDaemonException {
        return clusterDaemon.getRunTimeVmVersion();
    }

    public List<Attribute> getDynamicHostAttributes()
            throws ClusterDaemonException {

       /* Element root = new Element("attributes");
        Attribute dynamic = new Attribute("dynamic", "true");
        root.setAttribute(dynamic);

        Document document = new Document(root);*/

        Hashtable<String, String> table = clusterDaemon.getDynamicHostAttributes();
        List<Attribute> attributes = new ArrayList<Attribute>();
        for(Map.Entry<String, String> e : table.entrySet()) {
            attributes.add(new Attribute(e));
        }
        return attributes;
//        Iterator<String> it = table.keySet().iterator();

        /*Element attribute, key, value;

        while(it.hasNext()){
            String tableKey = it.next();

            attribute = new Element("attribute");
            key = new Element("key");
            value = new Element("value");
            key.setText(tableKey);
            value.setText(table.get(tableKey));
            attribute.addContent(key);
            attribute.addContent(value);

            root.addContent(attribute);
        }

        return document.toString();*/

    }

    public String checkServerState(String srvName)
            throws ClusterDaemonException {
        return String.valueOf(clusterDaemon.checkServerState(srvName));
    }

    public String getVmCurrentUsedMemory() throws ClusterDaemonException {
        return clusterDaemon.getVmCurrentUsedMemory();
    }

    public String getVmTotalMemory() throws ClusterDaemonException {
        return clusterDaemon.getVmTotalMemory();
    }

    public String getVmCurrentUsedHeapMemory() throws ClusterDaemonException {
        return clusterDaemon.getVmCurrentUsedHeapMemory();
    }

    public String getVmCurrentUsedNonHeapMemory() throws ClusterDaemonException {
        return clusterDaemon.getVmCurrentUsedNonHeapMemory();
    }

    public String getOsCurrentUsedSpace() throws ClusterDaemonException {
        return clusterDaemon.getOsCurrentUsedSpace();
    }

    public String getOsTotalSpace() throws ClusterDaemonException {
        return clusterDaemon.getOsTotalSpace();
    }
}
