package net.hyperic.hq.mx4j;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;

public class ExampleServer 
    implements ExampleServerMBean
{
    // ObjectNames
    public static final String INFO_OBJECT = "hyperic:type=ServerInfo";
    public static final String ECHO_OBJECT = "hyperic:type=EchoServer,name=";
    public static final String RMI_OBJECT  = "naming:type=rmiregistry";

    // JMX constants
    public static final String JMX_URL =
        "service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector";

    private long startTime;
    private int available;

    public ExampleServer() {
        this.startTime = System.currentTimeMillis();
        this.available = 1;
    }

    public Integer getAvailability() {
        return new Integer(available);
    }

    public Long getUptime() {
        return new Long(System.currentTimeMillis() - startTime);
    }

    public Long getTotalMemory() {
        return new Long(Runtime.getRuntime().totalMemory());
    }

    public Long getFreeMemory() {
        return new Long(Runtime.getRuntime().freeMemory());
    }

    private ThreadGroup getRootThreadGroup() {
        ThreadGroup group = Thread.currentThread().getThreadGroup();

        while (group.getParent() != null) {
            group = group.getParent();
        }

        return group;
    }

    public Integer getActiveThreadCount() {
        return new Integer(getRootThreadGroup().activeCount());
    }

    public Integer getActiveThreadGroupCount() {
        return new Integer(getRootThreadGroup().activeGroupCount());
    }

    private static void startRMIConnector(MBeanServer server) 
        throws Exception
    {
        ObjectName name = new ObjectName(RMI_OBJECT);

        server.createMBean("mx4j.tools.naming.NamingService", name, null);
        server.invoke(name, "start", null, null);

        JMXServiceURL jmxurl = new JMXServiceURL(JMX_URL);
        JMXConnectorServer connectorServer = 
            JMXConnectorServerFactory.newJMXConnectorServer(jmxurl, null, 
                                                            server);
        connectorServer.start();
    }

    public static void main(String[] args) 
        throws Exception
    {
        MBeanServer server = MBeanServerFactory.createMBeanServer();

        // Register MBean for monitoring server info.
        ObjectName name = new ObjectName(INFO_OBJECT);
        ExampleServer serverMBean = new ExampleServer();
        server.registerMBean(serverMBean, name);

        // Start RMI connection handler.
        startRMIConnector(server);

        // EchoService is a service that is run by the example server.
        name = new ObjectName(ECHO_OBJECT + "EchoService");
        EchoService echo = new EchoService("EchoService", 12345);
        server.registerMBean(echo, name);

        echo.run();
    }
}
