package edu.mit.drkp;

import java.io.IOException;
import java.net.InetAddress;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;
import java.net.UnknownHostException;

public class RPCServer
{
    private static RPCServer INSTANCE;
    
    private static final int port = 44266;

    private WebServer webServer;
    private XmlRpcServer xmlRpcServer;
    private PropertyHandlerMapping phm;
    private XmlRpcServerConfigImpl config;
    
    
    private RPCServer()
    {
        try {
            webServer = new WebServer(port, InetAddress.getByName("127.0.0.1"));
        } catch (UnknownHostException e) {
            throw new RuntimeException("localhost not found!", e);
        }

        xmlRpcServer = webServer.getXmlRpcServer();

        phm = new PropertyHandlerMapping();
        try {
            phm.addHandler("ping", edu.mit.drkp.Ping.class);
            phm.addHandler("gnutella", edu.mit.drkp.GnutellaRPCInterface.class);
        } catch (XmlRpcException e) {
            throw new RuntimeException("Failed to add XMLRPC handler", e);
        }

        
        xmlRpcServer.setHandlerMapping(phm);
        config = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
        config.setEnabledForExtensions(true);
        config.setContentLengthOptional(false);

        try {
            webServer.start();
        } catch (IOException e) {
            throw new RuntimeException("Failed to start web server", e);
        }

    }

    public static RPCServer getRPCServer()
    {
        if (INSTANCE == null) {
            INSTANCE = new RPCServer();
        }

        return INSTANCE;
    }
}
