package net.hyperic.hq.product.fabric;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.hyperic.hq.product.AutoServerDetector;
import net.hyperic.hq.product.FileServerDetector;
import net.hyperic.hq.product.PluginException;
import net.hyperic.hq.product.ServerDetector;
import net.hyperic.hq.product.ServerResource;
import net.hyperic.hq.product.ServiceResource;

import net.hyperic.util.config.ConfigResponse;

public class FabricServerDetector
    extends ServerDetector
    implements AutoServerDetector,
               FileServerDetector {

    //name of the binary is perl
    //first argument passed to perl endsWith("fabric_server.pl")
    private static final String PTQL_QUERY =
        "State.Name.eq=perl,Args.1.ew=fabric_server.pl";

    private static final String PROP_SERVICE = "service.name";
    private static final String SERVICE_NAME = "Service";

    //strip bin/fabric_server.pl
    private static String getInstallPath(String script) {
        File path = new File(script).getParentFile();

        if (path.getName().equals("bin")) {
            path = path.getParentFile();
        }
        if (path == null) {
            return ".";
        }

        return path.getAbsolutePath();
    }

    protected ServerResource createServerResource(String script) {
        ServerResource server =
            super.createServerResource(getInstallPath(script));

        //gets defaults from hq-plugin.xml
        setProductConfig(server, new ConfigResponse());

        //required to auto enable default metrics
        server.setMeasurementConfig();
        
        getLog().debug("Detected installpath=" + server.getInstallPath());

        return server;
    }

    //AutoServerDetector implementation
    public List getServerResources(ConfigResponse platformConfig) throws PluginException {
        List servers = new ArrayList();
        long[] pids = getPids(PTQL_QUERY);

        getLog().debug("PTQL query matched " + pids.length + " processes");
        
        for (int i=0; i<pids.length; i++) {
            String[] args = getProcArgs(pids[i]);

            getLog().debug(pids[i] + " args=" + Arrays.asList(args));
            
            //args[0] == /usr/bin/perl
            //args[1] == /.../bin/fabric_server.pl
            if (args.length < 2) {
                continue;
            }

            servers.add(createServerResource(args[1]));
        }

        return servers;
    }

    //FileServerDetector implementation
    public List getServerResources(ConfigResponse platformConfig, String script) throws PluginException {
        List servers = new ArrayList();

        servers.add(createServerResource(script));

        return servers;
    }

    //Auto-Discovery for services
    //ConfigResponse is filled in with config for the parent server.
    protected List discoverServices(ConfigResponse serverConfig)
        throws PluginException {
        List services = new ArrayList();

        //we hardcode the server names for this example
        String[] serviceNames = { "ftp", "http", "smtp" }; 

        for (int i=0; i<serviceNames.length; i++) {
            String name = serviceNames[i];
            ServiceResource service = new ServiceResource();
            //"Fabric 1.0 Service"
            service.setType(this, SERVICE_NAME);
            //getPlatform() + " " + name
            service.setServiceName(name);

            //will be used to replace %service.name% in the metric
            //templates defined in hq-plugin.xml
            ConfigResponse config = new ConfigResponse();
            config.setValue(PROP_SERVICE, name);
            service.setProductConfig(config);

            //required to auto-enable metrics for this resource
            service.setMeasurementConfig();
            services.add(service);
        }

        return services;
    }
}
