/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 org.apache.tajo.rpc;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.ResourceLeakDetector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public final class NettyUtils {
  private static final Log LOG = LogFactory.getLog(NettyUtils.class);
  
  private static final int DEFAULT_THREAD_NUM = Runtime.getRuntime().availableProcessors() * 2;
  private static final Object lockObjectForLoopGroup = new Object();
  private static final AtomicInteger serverCount = new AtomicInteger(0);

  public static final ByteBufAllocator ALLOCATOR;

  public enum GROUP {
    DEFAULT,
    FETCHER
  }

  private static final Map<GROUP, EventLoopGroup> eventLoopGroupMap =
      new ConcurrentHashMap<GROUP, EventLoopGroup>();

  static {
    if (RpcConstants.IS_TEST_MODE) {
      /* Disable pooling buffers for memory usage  */
      ALLOCATOR = UnpooledByteBufAllocator.DEFAULT;

      /* if you are finding memory leak, please enable this line */
      ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
    } else {
      ALLOCATOR = PooledByteBufAllocator.DEFAULT;
    }
  }

  private NettyUtils(){
  }

  /**
   * Get default EventLoopGroup of netty’s. servers and clients can shared it.
   */
  public static EventLoopGroup getDefaultEventLoopGroup() {
    return getSharedEventLoopGroup(GROUP.DEFAULT, DEFAULT_THREAD_NUM);
  }

  /**
   * Get EventLoopGroup of netty’s.
   *
   * @param clientId
   * @param threads
   * @return A EventLoopGroup by key
   */
  public static EventLoopGroup getSharedEventLoopGroup(GROUP clientId, int threads) {
    EventLoopGroup returnEventLoopGroup;

    synchronized (lockObjectForLoopGroup) {
      if (!eventLoopGroupMap.containsKey(clientId)) {
        eventLoopGroupMap.put(clientId, createEventLoopGroup(clientId.name(), threads));
      }

      returnEventLoopGroup = eventLoopGroupMap.get(clientId);
      if (isEventLoopGroupShuttingDown(returnEventLoopGroup)) {
        returnEventLoopGroup = createEventLoopGroup(clientId.name(), threads);
        eventLoopGroupMap.put(clientId, returnEventLoopGroup);
      }
    }

    return returnEventLoopGroup;
  }

  public static EventLoopGroup createEventLoopGroup(String name, int threads) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Create " + name + " EventLoopGroup. threads:" + threads);
    }

    ThreadFactoryBuilder builder = new ThreadFactoryBuilder();
    ThreadFactory clientFactory = builder.setNameFormat(name + " #%d").build();

    return createEventLoopGroup(threads, clientFactory);
  }

  protected static boolean isEventLoopGroupShuttingDown(EventLoopGroup eventLoopGroup) {
    return ((eventLoopGroup == null) || eventLoopGroup.isShuttingDown());
  }

  private static EventLoopGroup createEventLoopGroup(int threads, ThreadFactory factory) {
    return new NioEventLoopGroup(threads, factory);
  }

  /**
   * Server must release the external resources
   */
  public static ServerBootstrap createServerBootstrap(String name, int threads) {
    name = name + "-" + serverCount.incrementAndGet();

    EventLoopGroup eventLoopGroup = createEventLoopGroup(name, threads);
    return new ServerBootstrap().group(eventLoopGroup, eventLoopGroup);
  }

  public static void shutdownGracefully() {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Shutdown Shared RPC Pool");
    }
    synchronized (lockObjectForLoopGroup) {
      for (EventLoopGroup eventLoopGroup : eventLoopGroupMap.values()) {
        try {
          shutdown(eventLoopGroup).sync();
        } catch (InterruptedException e) {
          //ignore
        }
      }
      eventLoopGroupMap.clear();
    }
  }

  public static io.netty.util.concurrent.Future shutdown(EventLoopGroup eventLoopGroup) {
    if (eventLoopGroup != null) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Shutdown EventLoopGroup :" + eventLoopGroup.toString());
      }

      return eventLoopGroup.shutdownGracefully();
    }
    return null;
  }
}
