//import com.sun.jndi.dns.DnsContext;

import javax.naming.InitialContext;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
import java.util.stream.Stream;

public class TestJndiIpv6 {
    public static void main(final String[] args) {
        //testStream().forEach(TestJndiIpv6::testDnsContext);
        testStream().forEach(TestJndiIpv6::testInitialContext);
        testStream().forEach(TestJndiIpv6::testInitialDirContext);
    }

    private static Stream<String> testStream() {
        return Stream.of(
                "1.1.1.1", // IPv4 address
                "2606:4700:4700::1111", // IPv6 address
                "[2606:4700:4700::1111]", // BSD-syle IPv6 address
                "::ffff:1.1.1.1", // IPv6-mapped IPv4 address in format 3
                "[::ffff:1.1.1.1]", // BSD-style IPv6-mapped IPv4 address in format 3
                "::ffff:101:101", // BSD-style IPv6-mapped IPv4 address
                "[::ffff:101:101]", // IPv6-mapped IPv4 address
                // Passing an empty string will use the configuration in /etc/resolv.conf.
                // To test the failure case, either convert an existing IPv6 address to the y:y:y:y:y:y:x.x.x.x format
                // or use an IPv6-mapped IPv4 address -- e.g. add `nameserver ::1111:1.1.1.1` or `nameserver ::1111:8.8.8.8`.
                ""
        );
    }

    // /**
    // * Tests DnsContext directly, but requires `--add-opens jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED` when
    // * executed in JDK 9+.
    // */
    // private static void testDnsContext(final String server) {
    // final Hashtable<Object, Object> env = new Hashtable<>();
    // env.put("java.naming.provider.url", "dns:");
    // env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
    // try {
    // final DnsContext ctx = new DnsContext(".", new String[]{server}, env);
    // ctx.lookup("example.com");
    // System.out.println("[Direct use of com.sun.jndi.dns.DnsContext] Server IP `" + server + "` succeeds.");
    // } catch (final Exception e) {
    // System.out.println("[Direct use of com.sun.jndi.dns.DnsContext] Server IP `" + server + "` fails with: " + e);
    // }
    // }

    private static void testInitialContext(final String server) {
        final Hashtable<Object, Object> env = new Hashtable<>();
        env.put("java.naming.provider.url", "dns://" + server);
        env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
        try {
            final InitialContext ctx = new InitialContext(env);
            ctx.lookup("example.com");
            System.out.println("[Use of javax.naming.InitialContext]: Server IP `" + server + "` succeeds.");
        } catch (final Exception e) {
            System.out.println("[Use of javax.naming.InitialContext]: Server IP `" + server + "` fails with: " + e);
            e.printStackTrace();
        }
    }

    private static void testInitialDirContext(final String server) {
        final Hashtable<Object, Object> env = new Hashtable<>();
        env.put("java.naming.provider.url", "dns://" + server);
        env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
        try {
            final InitialDirContext dirContext = new InitialDirContext(env);
            final Attributes attributes = dirContext.getAttributes("example.com", new String[]{"A"});
            final Attribute attribute = attributes.get("A");
            System.out.println("[Use of javax.naming.directory.InitialDirContext]: Server IP `" + server + "` succeeds.");
        } catch (final Exception e) {
            System.out.println("[Use of javax.naming.directory.InitialDirContext]: Server IP `" + server + "` fails with: " + e);
        }
    }
} 