package com.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
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 io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Syslog 服务器主类，支持 TCP 和 UDP 协议
 */
public class SyslogServer {
    private static final Logger logger = LoggerFactory.getLogger(SyslogServer.class);

    private final int tcpPort;
    private final int udpPort;

    public SyslogServer(int tcpPort, int udpPort) {
        this.tcpPort = tcpPort;
        this.udpPort = udpPort;
    }

    public void start() throws InterruptedException {

        // 启动 TCP 服务器
        startTcpServer();
        // 启动 UDP 服务器
        startUdpServer();
    }

    private void startTcpServer() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new SyslogTcpChannelInitializer())
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(tcpPort).sync();
            logger.info("TCP Syslog server started on port {}", tcpPort);

            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    private void startUdpServer() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .handler(new SyslogUdpChannelInitializer())
                    .option(ChannelOption.SO_BROADCAST, true);

            ChannelFuture f = b.bind(udpPort).sync();
            logger.info("UDP Syslog server started on port {}", udpPort);

            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int tcpPort = args.length > 0 ? Integer.parseInt(args[0]) : 514;
        int udpPort = args.length > 1 ? Integer.parseInt(args[1]) : 514;

        SyslogServer server = new SyslogServer(tcpPort, udpPort);
        server.start();
    }
}