/**
 * Copyright 2013 Facebook, Inc.
 *
 * Licensed 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 com.facebook.nifty.core;

import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.group.ChannelGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class ShutdownUtil
{
    private static final Logger log = LoggerFactory.getLogger(ShutdownUtil.class);

    public static void shutdownChannelFactory(ChannelFactory channelFactory,
                                              ExecutorService bossExecutor,
                                              ExecutorService workerExecutor,
                                              ChannelGroup allChannels)
    {
        // Close all channels
        if (allChannels != null) {
            closeChannels(allChannels);
        }

        // Shutdown the channel factory
        if (channelFactory != null) {
            channelFactory.shutdown();
        }

        // Stop boss threads
        if (bossExecutor != null) {
            shutdownExecutor(bossExecutor, "bossExecutor");
        }

        // Finally stop I/O workers
        if (workerExecutor != null) {
            shutdownExecutor(workerExecutor, "workerExecutor");
        }
    }

    public static void closeChannels(ChannelGroup allChannels)
    {
        if (allChannels.size() > 0)
        {
            // TODO : allow an option here to control if we need to drain connections and wait instead of killing them all
            try {
                log.info("Closing " + allChannels.size() + " open client connections");
                if (!allChannels.close().await(5, TimeUnit.SECONDS)) {
                    log.warn("Failed to close all open client connections");
                }
            } catch (InterruptedException e) {
                log.warn("Interrupted while closing client connections");
                Thread.currentThread().interrupt();
            }
        }
    }

    // TODO : make wait time configurable ?
    public static void shutdownExecutor(ExecutorService executor, final String name)
    {
        executor.shutdown();
        try {
            log.info("Waiting for {} to shutdown", name);
            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                log.warn("{} did not shutdown properly", name);
            }
        }
        catch (InterruptedException e) {
            log.warn("Interrupted while waiting for {} to shutdown", name);
            Thread.currentThread().interrupt();
        }
    }
}

@@ -1,11 +1,10 @@
 /*
-*
 %0A * Copy
@@ -9,16 +9,25 @@
 pyright 
+(C) 2012-
 2013 Fac
@@ -111,16 +111,19 @@
 e%22);
+%0A *
  you may
 %0A * 
@@ -118,19 +118,16 @@
  you may
-%0A *
  not use
@@ -175,16 +175,19 @@
 License.
+%0A *
  You may
@@ -193,19 +193,16 @@
 y obtain
-%0A *
  a copy 
@@ -224,20 +224,16 @@
 at%0A *%0A *
-    
  http://
@@ -414,16 +414,19 @@
 SIS,
+%0A *
  WITHOUT
 %0A * 
@@ -421,19 +421,16 @@
  WITHOUT
-%0A *
  WARRANT
@@ -490,16 +490,19 @@
 ied.
+%0A *
  See the
 %0A * 
@@ -497,19 +497,16 @@
  See the
-%0A *
  License
@@ -557,16 +557,19 @@
 ions and
+%0A *
  limitat
@@ -572,19 +572,16 @@
 itations
-%0A *
  under t

Fix license:check failure from slight license text mismatch