/**
 * 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.avro.ipc;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;

import org.apache.avro.ipc.NettyTransportCodec.NettyDataPack;
import org.apache.avro.ipc.NettyTransportCodec.NettyFrameDecoder;
import org.apache.avro.ipc.NettyTransportCodec.NettyFrameEncoder;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.execution.ExecutionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Netty-based RPC {@link Server} implementation.
 */
public class NettyServer implements Server {
  private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class
      .getName());

  private final Responder responder;

  private final Channel serverChannel;
  private final ChannelGroup allChannels = new DefaultChannelGroup(
      "avro-netty-server");
  private final ChannelFactory channelFactory;
  private final CountDownLatch closed = new CountDownLatch(1);
  private final ExecutionHandler executionHandler;            
  
  public NettyServer(Responder responder, InetSocketAddress addr) {
    this(responder, addr, new NioServerSocketChannelFactory
         (Executors .newCachedThreadPool(), Executors.newCachedThreadPool()));
  }
  
  public NettyServer(Responder responder, InetSocketAddress addr,
                     ChannelFactory channelFactory) {
      this(responder, addr, channelFactory, null);
  }

  /**
   * @param executionHandler if not null, will be inserted into the Netty
   *                         pipeline. Use this when your responder does
   *                         long, non-cpu bound processing (see Netty's
   *                         ExecutionHandler javadoc).
   * @param pipelineFactory  Avro-related handlers will be added on top of
   *                         what this factory creates
   */
  public NettyServer(Responder responder, InetSocketAddress addr,
                     ChannelFactory channelFactory,
                     final ChannelPipelineFactory pipelineFactory,
                     final ExecutionHandler executionHandler) {
    this.responder = responder;
    this.channelFactory = channelFactory;
    this.executionHandler = executionHandler;
    ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
      @Override
      public ChannelPipeline getPipeline() throws Exception {
        ChannelPipeline p = pipelineFactory.getPipeline();
        p.addLast("frameDecoder", new NettyFrameDecoder());
        p.addLast("frameEncoder", new NettyFrameEncoder());
        if (executionHandler != null) {
          p.addLast("executionHandler", executionHandler);
        }
        p.addLast("handler", new NettyServerAvroHandler());
        return p;
      }
    });
    serverChannel = bootstrap.bind(addr);
    allChannels.add(serverChannel);
  }

  /**
   * @param executionHandler if not null, will be inserted into the Netty
   *                         pipeline. Use this when your responder does
   *                         long, non-cpu bound processing (see Netty's
   *                         ExecutionHandler javadoc).
   */
  public NettyServer(Responder responder, InetSocketAddress addr,
                     ChannelFactory channelFactory,
                     final ExecutionHandler executionHandler) {
    this(responder, addr, channelFactory, new ChannelPipelineFactory() {
      @Override
      public ChannelPipeline getPipeline() throws Exception {
        return Channels.pipeline();
      }
    }, executionHandler);
  }
    
  @Override
  public void start() {
    // No-op.
  }
  
  @Override
  public void close() {
    ChannelGroupFuture future = allChannels.close();
    future.awaitUninterruptibly();
    channelFactory.releaseExternalResources();
    closed.countDown();
  }
  
  @Override
  public int getPort() {
    return ((InetSocketAddress) serverChannel.getLocalAddress()).getPort();
  }

  @Override
  public void join() throws InterruptedException {
    closed.await();
  }
  
  /**
   *
   * @return The number of clients currently connected to this server.
   */
  public int getNumActiveConnections() {
    //allChannels also contains the server channel, so exclude that from the
    //count.
    return allChannels.size() - 1;
  }

  /**
   * Avro server handler for the Netty transport 
   */
  class NettyServerAvroHandler extends SimpleChannelUpstreamHandler {

    private NettyTransceiver connectionMetadata = new NettyTransceiver();
    
    @Override
    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
        throws Exception {
      if (e instanceof ChannelStateEvent) {
        LOG.info(e.toString());
      }
      super.handleUpstream(ctx, e);
    }

    @Override
    public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
        throws Exception {
      allChannels.add(e.getChannel());
      super.channelOpen(ctx, e);
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
      try {
        NettyDataPack dataPack = (NettyDataPack) e.getMessage();
        List<ByteBuffer> req = dataPack.getDatas();
        List<ByteBuffer> res = responder.respond(req, connectionMetadata);
        // response will be null for oneway messages.
        if(res != null) {
          dataPack.setDatas(res);
          e.getChannel().write(dataPack);          
        }
      } catch (IOException ex) {
        LOG.warn("unexpect error");
      }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
      LOG.warn("Unexpected exception from downstream.", e.getCause());
      e.getChannel().close();
      allChannels.remove(e.getChannel());
    }

    @Override
    public void channelClosed(
            ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
      LOG.info("Connection to {} disconnected.",
              e.getChannel().getRemoteAddress());
      super.channelClosed(ctx, e);
      e.getChannel().close();
      allChannels.remove(e.getChannel());
    }

  }
}
