/*
 * Copyright 2014 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package io.netty.resolver.dns;

import io.netty.channel.ChannelFactory;
import io.netty.channel.EventLoop;
import io.netty.channel.ReflectiveChannelFactory;
import io.netty.channel.socket.DatagramChannel;
import io.netty.resolver.AddressResolver;
import io.netty.resolver.AddressResolverGroup;
import io.netty.resolver.InetSocketAddressResolver;
import io.netty.resolver.NameResolver;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.StringUtil;
import io.netty.util.internal.UnstableApi;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.ConcurrentMap;

import static io.netty.resolver.dns.DnsNameResolver.ANY_LOCAL_ADDR;
import static io.netty.util.internal.PlatformDependent.newConcurrentHashMap;

/**
 * A {@link AddressResolverGroup} of {@link DnsNameResolver}s.
 */
@UnstableApi
public class DnsAddressResolverGroup extends AddressResolverGroup<InetSocketAddress> {

    private final ChannelFactory<? extends DatagramChannel> channelFactory;
    private final InetSocketAddress localAddress;
    private final DnsServerAddresses nameServerAddresses;

    private final ConcurrentMap<String, Promise<InetAddress>> resolvesInProgress = newConcurrentHashMap();
    private final ConcurrentMap<String, Promise<List<InetAddress>>> resolveAllsInProgress = newConcurrentHashMap();

    public DnsAddressResolverGroup(
            Class<? extends DatagramChannel> channelType, DnsServerAddresses nameServerAddresses) {
        this(channelType, ANY_LOCAL_ADDR, nameServerAddresses);
    }

    public DnsAddressResolverGroup(
            Class<? extends DatagramChannel> channelType,
            InetSocketAddress localAddress, DnsServerAddresses nameServerAddresses) {
        this(new ReflectiveChannelFactory<DatagramChannel>(channelType), localAddress, nameServerAddresses);
    }

    public DnsAddressResolverGroup(
            ChannelFactory<? extends DatagramChannel> channelFactory, DnsServerAddresses nameServerAddresses) {
        this(channelFactory, ANY_LOCAL_ADDR, nameServerAddresses);
    }

    public DnsAddressResolverGroup(
            ChannelFactory<? extends DatagramChannel> channelFactory,
            InetSocketAddress localAddress, DnsServerAddresses nameServerAddresses) {
        this.channelFactory = channelFactory;
        this.localAddress = localAddress;
        this.nameServerAddresses = nameServerAddresses;
    }

    @Override
    protected final AddressResolver<InetSocketAddress> newResolver(EventExecutor executor) throws Exception {
        if (!(executor instanceof EventLoop)) {
            throw new IllegalStateException(
                    "unsupported executor type: " + StringUtil.simpleClassName(executor) +
                    " (expected: " + StringUtil.simpleClassName(EventLoop.class));
        }

        return newResolver((EventLoop) executor, channelFactory, localAddress, nameServerAddresses);
    }

    /**
     * Creates a new {@link DnsNameResolver}. Override this method to create an alternative {@link DnsNameResolver}
     * implementation or override the default configuration.
     */
    protected AddressResolver<InetSocketAddress> newResolver(
            EventLoop eventLoop, ChannelFactory<? extends DatagramChannel> channelFactory,
            InetSocketAddress localAddress, DnsServerAddresses nameServerAddresses) throws Exception {

        final NameResolver<InetAddress> resolver = new InflightNameResolver<InetAddress>(
                eventLoop,
                new DnsNameResolverBuilder(eventLoop)
                        .channelFactory(channelFactory)
                        .localAddress(localAddress)
                        .nameServerAddresses(nameServerAddresses)
                        .build(),
                resolvesInProgress,
                resolveAllsInProgress);

        return new InetSocketAddressResolver(eventLoop, resolver);
    }
}

@@ -3110,24 +3110,61 @@
 ses;%0A    %7D%0A%0A
+    @SuppressWarnings(%22deprecation%22)%0A
     @Overrid
@@ -3680,29 +3680,36 @@
   * 
-C
+@dep
 re
+c
 ate
-s a new
+d Override
  %7B@link 
 DnsN
@@ -3696,35 +3696,36 @@
 Override %7B@link 
-Dns
+#new
 NameResolver%7D. O
@@ -3724,149 +3724,100 @@
 lver
-%7D. Override this method to create an alternative %7B@link DnsNameResolver%7D%0A     * implementation or override the default configuration.%0A     */
+(EventLoop, ChannelFactory, InetSocketAddress, DnsServerAddresses)%7D.%0A     */%0A    @Deprecated
 %0A   
@@ -4210,83 +4210,597 @@
  new
- DnsNameResolverBuilder(eventLoop)%0A                        .channelFactory(
+NameResolver(eventLoop, channelFactory, localAddress, nameServerAddresses),%0A                resolvesInProgress,%0A                resolveAllsInProgress);%0A%0A        return new InetSocketAddressResolver(eventLoop, resolver);%0A    %7D%0A%0A    /**%0A     * Creates a new %7B@link NameResolver%7D. Override this method to create an alternative %7B@link NameResolver%7D%0A     * implementation or override the default configuration.%0A     */%0A    protected NameResolver%3CInetAddress%3E newNameResolver(EventLoop eventLoop,%0A                                                        ChannelFactory%3C? extends DatagramChannel%3E 
 chan
@@ -4809,17 +4809,17 @@
 lFactory
-)
+,
 %0A       
@@ -4839,22 +4839,58 @@
     
-.local
+                                InetSocket
 Address
-(
+ 
 loca
@@ -4897,17 +4897,17 @@
 lAddress
-)
+,
 %0A       
@@ -4923,21 +4923,51 @@
         
-.name
+                                Dns
 ServerAd
@@ -4973,17 +4973,17 @@
 ddresses
-(
+ 
 nameServ
@@ -4998,119 +4998,172 @@
 ses)
-%0A                        .build(),%0A                resolvesInProgress,%0A                resolveAllsInProg
+ throws Exception %7B%0A        return new DnsNameResolverBuilder(eventLoop)%0A                .channelFactory(channelFactory)%0A                .localAddress(localAdd
 ress)
-;%0A
 %0A   
@@ -5171,64 +5171,81 @@
     
-return new InetSocket
+        .nameServer
 Address
-R
 es
-olver(eventLoop, resolver
+(nameServerAddresses)%0A                .build(
 );%0A 

Make DnsAddressResolverGroup easier to extend