package com.mortals.xhx.daemon.netty.server.controlserver;

import com.mortals.xhx.module.device.service.DeviceService;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.net.Inet4Address;

@Component
@CommonsLog
public class ControlServer {

    private Bootstrap bootstrap;
    private Channel channel;
    /**
     * Worker
     */
    private EventLoopGroup workGroup;

    private volatile boolean isClosed;

    @Autowired
    private DeviceService deviceService;


    public void run(int port) {
        try {
            initServerBootstrap();
            ChannelFuture future = bootstrap.bind(port).sync();
            channel = future.channel();
            if (channel != null && channel.isOpen() && channel.isActive() && channel.isRegistered() && channel.isWritable()) {
                log.info(String.format("ControlUDP启动成功，ip【%1$s】\tport【%2$d】", Inet4Address.getLocalHost().getHostAddress(), port));
                isClosed = false;
            } else {
                log.info("NettyControlUDP启动");
            }

            future.awaitUninterruptibly();
            channel.closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                workGroup.shutdownGracefully();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                workGroup = null;
            }
        }
    }

    @PreDestroy
    public void release() {
        isClosed = true;
        closeChannel();
        closeServerBootstrap();
    }

    /**
     * 初始化ServerBootstrap
     */
    private void initServerBootstrap() {
        try {
            closeServerBootstrap();// 先关闭之前的bootstrap

            workGroup = new NioEventLoopGroup();
            bootstrap = new Bootstrap();
            bootstrap.group(workGroup)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new ControlServerInitializer(deviceService));
                    //.handler(new NettyUDPServerHandler());
        } catch (Exception e) {
            log.error("启动异常", e);
        }
    }

    private void closeServerBootstrap() {
        try {
            if (bootstrap != null) {
                bootstrap.config().group().shutdownGracefully();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bootstrap = null;
        }
    }

    private void closeChannel() {
        try {
            if (channel != null) {
                try {
                    channel.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    channel.eventLoop().shutdownGracefully();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            channel = null;
        }
    }


}
