package com.imdroid.vermgr.service;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
@Slf4j
public class VersionServer {
    @Value("${version_server_port}")
    private int data_port;

    @PostConstruct
    public void init() {

        // 创建socket服务，线程阻塞
        new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("dtu config server starting...");
                // Configure the server.
                EventLoopGroup bossGroup = new NioEventLoopGroup(1);
                EventLoopGroup workerGroup = new NioEventLoopGroup();

                try {
                    ServerBootstrap b = new ServerBootstrap();
                    b.group(bossGroup, workerGroup)
                            .channel(NioServerSocketChannel.class)
                            .option(ChannelOption.SO_BACKLOG, 100)
                            //.option(ChannelOption.SO_REUSEADDR, true)
                            .handler(new LoggingHandler(LogLevel.INFO))
                            .childHandler(new ChannelInitializer<SocketChannel>() {
                                @Override
                                public void initChannel(SocketChannel ch) throws Exception {
                                    ChannelPipeline p = ch.pipeline();
                                    //p.addLast(new LoggingHandler(LogLevel.INFO));
                                    p.addLast(new ByteArrayDecoder());
                                    p.addLast(new ByteArrayEncoder());
                                    p.addLast(new IdleStateHandler(300, 300, 300));    //设置心跳超时时间，秒
                                    p.addLast(new VersionHandler());
                                }
                            });

                    // Start the server.
                    ChannelFuture f = b.bind(data_port).sync();

                    // Wait until the server socket is closed.
                    f.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    log.error("error occurred during version server running: "+e);
                } finally {
                    // Shut down all event loops to terminate all threads.
                    bossGroup.shutdownGracefully();
                    workerGroup.shutdownGracefully();
                }
            }
        }).start();
    }
}
