import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.StringTokenizer;


public class DNSSRV {

    private static DirContext context;

    /**
     * Internal DNS that allows to specify target IP addresses and ports to
     * use for domains. The internal DNS will be checked up before performing
     * an actual DNS SRV lookup.
     */
    private static Map<String, HostAddress> dnsOverride;

    static {
        try {
            Hashtable<String,String> env = new Hashtable<String,String>();
            env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
            context = new InitialDirContext(env);
        }
        catch (Exception e) {
            System.out.println("error in Map");
        }
    }


    /**
     * Encapsulates a hostname and port.
     */
    public static class HostAddress {

        private String host;
        private int port;

        private HostAddress(String host, int port) {
            this.host = host;
            this.port = port;
        }

        /**
         * Returns the hostname.
         *
         * @return the hostname.
         */
        public String getHost() {
            return host;
        }

       /**
         * Returns the port.
         *
         * @return the port.
         */
        public int getPort() {
            return port;
        }

        public String toString() {
            return host + ":" + port;
        }
    }


    public static HostAddress resolveXMPPServerDomain(String domain, int defaultPort) {
        if (context == null) {
	    System.out.println("context is null");
            return new HostAddress(domain, defaultPort);
        }

	String host = domain;
	int port = defaultPort;
	try {
	    System.out.println("try...");
	    Attributes dnsLookup =
		context.getAttributes("_xmpp-server._tcp." + domain, new String[]{"SRV"});
	    String srvRecord = (String)dnsLookup.get("SRV").get();
            String [] srvRecordEntries = srvRecord.split(" ");
            port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length-2]);
            host = srvRecordEntries[srvRecordEntries.length-1];
        }
        catch (Exception e) {
            // Attempt lookup with older "jabber" name.
	    System.err.println(e.getMessage());
	    e.printStackTrace();
            try {
                Attributes dnsLookup =
                        context.getAttributes("_jabber._tcp." + domain, new String[]{"SRV"});
                String srvRecord = (String)dnsLookup.get("SRV").get();
                String [] srvRecordEntries = srvRecord.split(" ");
                port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length-2]);
                host = srvRecordEntries[srvRecordEntries.length-1];
            }
	    catch (Exception e2) {
		// Do nothing
		System.out.println("Catch 11");
		System.err.println(e2.getMessage());
	    }
	}
	// Host entries in DNS should end with a ".".
        if (host.endsWith(".")) {
            host = host.substring(0, host.length()-1);
        }

	return new HostAddress(host, port);
    }



    public static void main(String argv[]) {
        String hostname = "google.com";
	int port = 5269;
	String realHostname = null;
	int realPort = port;


	HostAddress address = resolveXMPPServerDomain(hostname, port);
	realHostname = address.getHost();
	realPort = address.getPort();
	
	System.out.println("Hostname: " + hostname + ", resolved hostname: " +
			   realHostname);
    }
}
