package io.lettuce.core.resource;

import io.lettuce.core.internal.LettuceClassUtils;
import io.netty.channel.socket.SocketChannel;
import io.netty.resolver.AddressResolverGroup;
import io.netty.resolver.DefaultAddressResolverGroup;
import io.netty.resolver.dns.DefaultDnsCache;
import io.netty.resolver.dns.DefaultDnsCnameCache;
import io.netty.resolver.dns.DnsAddressResolverGroup;
import io.netty.resolver.dns.DnsNameResolverBuilder;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

/**
 * Wraps and provides {@link AddressResolverGroup} classes. This is to protect the user from {@link ClassNotFoundException}'s
 * caused by the absence of the {@literal netty-dns-resolver} library during runtime. This class will be deleted when
 * {@literal netty-dns-resolver} becomes mandatory. Internal API.
 *
 * @author Yohei Ueki
 * @author Mark Paluch
 * @since 6.1
 */
class AddressResolverGroupProvider {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(AddressResolverGroupProvider.class);

    private static final AddressResolverGroup<?> ADDRESS_RESOLVER_GROUP;

    static {
        boolean dnsResolverAvailable = LettuceClassUtils.isPresent("io.netty.resolver.dns.DnsAddressResolverGroup");

        // create addressResolverGroup instance via Supplier to avoid NoClassDefFoundError.
        AddressResolverGroup<?> group;
        if (dnsResolverAvailable) {
            logger.debug("Starting with netty's non-blocking DNS resolver library");
            group = AddressResolverGroupProvider.defaultDnsAddressResolverGroup();
        } else {
            logger.debug("Starting without optional netty's non-blocking DNS resolver library");
            group = DefaultAddressResolverGroup.INSTANCE;
        }
        ADDRESS_RESOLVER_GROUP = group;
    }

    /**
     * Returns the {@link AddressResolverGroup} for DNS resolution.
     *
     * @return the {@link DnsAddressResolverGroup} if {@literal netty-dns-resolver} is available, otherwise return
     *         {@link DefaultAddressResolverGroup#INSTANCE}.
     */
    static AddressResolverGroup<?> addressResolverGroup() {
        return ADDRESS_RESOLVER_GROUP;
    }

    private static AddressResolverGroup<?> defaultDnsAddressResolverGroup() {
        return new DnsAddressResolverGroup(new DnsNameResolverBuilder().channelType(Transports.datagramChannelClass())
                .socketChannelType(Transports.socketChannelClass().asSubclass(SocketChannel.class))
                .cnameCache(new DefaultDnsCnameCache()).resolveCache(new DefaultDnsCache()));
    }

}

@@ -1294,100 +1294,8 @@
 );%0A%0A
-        // create addressResolverGroup instance via Supplier to avoid NoClassDefFoundError.%0A
     
@@ -1325,24 +1325,24 @@
 p%3C?%3E group;%0A
+
         if (
@@ -1474,38 +1474,9 @@
 p = 
-AddressResolverGroupProvider.d
+D
 efau
@@ -1500,18 +1500,32 @@
 verGroup
-()
+Wrapper.INSTANCE
 ;%0A      
@@ -2124,31 +2124,28 @@
  %7D%0A%0A    
-private static 
+// Wraps Dns
 AddressR
@@ -2160,13 +2160,66 @@
 roup
-%3C?%3E d
+ to avoid NoClassDefFoundError.%0A    private static class D
 efau
@@ -2239,37 +2239,43 @@
 esolverGroup
-()
+Wrapper
  %7B%0A
+%0A
         
 return new D
@@ -2262,22 +2262,57 @@
         
-return
+static AddressResolverGroup%3C?%3E INSTANCE =
  new Dns
@@ -2332,16 +2332,33 @@
 erGroup(
+%0A                
 new DnsN
@@ -2441,16 +2441,24 @@
         
+       
+ 
 .socketC
@@ -2549,16 +2549,24 @@
         
+        
 .cnameCa
@@ -2635,16 +2635,17 @@
 he()));%0A
+%0A
     %7D%0A%0A%7D

Fix NoClassDefFoundError when missing netty-dns-resolver #1546