package org.mitallast.queue.transport.http;

import com.google.inject.Inject;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.mitallast.queue.QueueException;
import org.mitallast.queue.common.component.AbstractLifecycleComponent;
import org.mitallast.queue.common.settings.Settings;
import org.mitallast.queue.rest.RestController;

public class HttpServer extends AbstractLifecycleComponent {

    private int port;
    private int backlog;
    private boolean keepAlive;
    private boolean reuseAddress;
    private boolean tcpNoDelay;

    private RestController restController;


    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ServerBootstrap bootstrap;
    private Channel channel;

    @Inject
    public HttpServer(Settings settings, RestController restController) {
        super(settings);
        this.port = settings.getAsInt("port", 8080);
        this.backlog = settings.getAsInt("backlog", 65536);
        this.reuseAddress = settings.getAsBoolean("reuse_address", true);
        this.keepAlive = settings.getAsBoolean("keep_alive", true);
        this.tcpNoDelay = settings.getAsBoolean("tcp_no_delay", true);
        this.restController = restController;
    }

    @Override
    protected void doStart() throws QueueException {
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpServerInitializer(new HttpServerHandler(restController)))
                    .option(ChannelOption.SO_BACKLOG, backlog)
                    .option(ChannelOption.SO_REUSEADDR, reuseAddress)
                    .option(ChannelOption.SO_KEEPALIVE, keepAlive)
                    .option(ChannelOption.TCP_NODELAY, tcpNoDelay)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT);
            channel = bootstrap.bind(port).sync().channel();
        } catch (InterruptedException e) {
            throw new QueueException(e);
        }
    }

    @Override
    protected void doStop() throws QueueException {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        try {
            channel.closeFuture().sync();
        } catch (InterruptedException e) {
            throw new QueueException(e);
        }
        channel = null;
        bootstrap = null;
        workerGroup = null;
        bossGroup = null;
    }

    @Override
    protected void doClose() throws QueueException {

    }
}

@@ -189,148 +189,9 @@
 nel.
-AdaptiveRecvByteBufAllocator;%0Aimport io.netty.channel.Channel;%0Aimport io.netty.channel.ChannelOption;%0Aimport io.netty.channel.EventLoopGroup
+*
 ;%0Aim
@@ -569,24 +569,49 @@
 omponent %7B%0A%0A
+    private String host;%0A
     private 
@@ -842,34 +842,51 @@
 ate 
-EventLoopGroup workerGroup
+Class%3C? extends ServerChannel%3E channelClass
 ;%0A  
@@ -1063,16 +1063,71 @@
 tings);%0A
+        this.host = settings.get(%22host%22, %22127.0.0.1%22);%0A
         
@@ -1621,45 +1621,51 @@
     
-workerGroup = new NioEventLoopGroup()
+channelClass = NioServerSocketChannel.class
 ;%0A  
@@ -1764,21 +1764,8 @@
 roup
-, workerGroup
 )%0A  
@@ -1795,32 +1795,16 @@
 nel(
-NioServerSocketC
+c
 hannel
-.c
+C
 lass
@@ -2590,20 +2590,68 @@
 ind(
-port).sync()
+host, port)%0A                    .sync()%0A                    
 .cha
@@ -2869,50 +2869,8 @@
 ();%0A
-        workerGroup.shutdownGracefully();%0A
     
@@ -3031,32 +3031,32 @@
 channel = null;%0A
+
         bootstra
@@ -3069,36 +3069,8 @@
 ll;%0A
-        workerGroup = null;%0A
     

use only boss group; use host for better performance