package com.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import com.kafka.kafkaProducer;
import com.Modules.Device.DeviceProcess;
import com.haobang.util.Sm4Util;
import com.haobang.config.AppConfig;
/**
 * Syslog 消息处理器
 */
public class SyslogMessageHandler extends SimpleChannelInboundHandler<Object> {
    private static final Logger logger = LoggerFactory.getLogger(SyslogMessageHandler.class);
    private static final Charset SYSLOG_CHARSET = AppConfig.getSyslogCharset();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        String message;
        String source;
        String source_ip;
        String networkProtocol;
        int source_port;
        if (msg instanceof DatagramPacket) {
            // UDP 消息处理
            DatagramPacket packet = (DatagramPacket) msg;
            message = packet.content().toString(SYSLOG_CHARSET);
            source_ip=packet.sender().getAddress().getHostAddress();
            source_port=packet.sender().getPort();
            source = packet.sender().getAddress().getHostAddress() + ":" + packet.sender().getPort();
            networkProtocol="UDP";
            logger.info("Received syslog from {}: {}", source, message);
        } else if (msg instanceof String) {
            // TCP 消息处理
            message = (String) msg;
            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
            source = remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort();
            source_ip=remoteAddress.getAddress().getHostAddress();
            source_port=remoteAddress.getPort();
            networkProtocol="TCP";
            logger.info("Received syslog from {}: {}", source, message);
        } else {
            logger.warn("Received unknown message type: {}", msg.getClass().getName());
            return;
        }
        DeviceProcess deviceProcess   = new DeviceProcess(source_ip);
        try {
            //日志推送的设备信息进行鉴权处理
            int deviceId = deviceProcess.getDeviceID(source_ip);
            if (deviceId < 0) {
                logger.info("syslog message 的请求设备IP:{}非系统注册，暂不做处理！",source_ip);
                //创建未知设备
                deviceProcess.saveDeviceUnknow(networkProtocol);
                return;
            }
            if (!deviceProcess.IsBelongDeviceCollectTask()) {
                logger.info("syslog message 的请求设备IP:{}不归属当前采集探针，暂不做处理！",source_ip);
                return;
            }
            //插入PG库接收记录
            deviceProcess.saveDeviceReceiveLog(message,true);
            kafkaProducer.messagePush(deviceProcess.getDeviceDevice(), message, deviceProcess.getDeviceReceiveLog().getReceiveTimeStr());

        } catch (Exception e) {
            //记录日志推送失败
            deviceProcess.saveDeviceReceiveLog(message,false);
            logger.warn("Failed to Push syslog message",  e);

        }
        // 处理 Syslog 消息
        //processSyslogMessage(message.trim(), source);
    }

    private void processSyslogMessage(String message, String source) {
        // 这里可以添加 Syslog 消息解析逻辑
        // 根据 RFC 3164 或 RFC 5424 解析消息
        System.out.println("Received syslog from "+  source +", msg:"+ message);
        logger.info("Received syslog from {}: {}", source, message);


        try {
            SyslogMessage syslogMsg = parseSyslogMessage(message);
            logger.info("Parsed syslog - Facility: {}, Severity: {}, Timestamp: {}, Host: {}, Message: {}",
                    syslogMsg.getFacility(),
                    syslogMsg.getSeverity(),
                    syslogMsg.getTimestamp(),
                    syslogMsg.getHostname(),
                    syslogMsg.getMessage());

            // 这里可以添加消息存储或其他处理逻辑
            // storeToDatabase(syslogMsg);

        } catch (Exception e) {
            logger.warn("Failed to parse syslog message: {}", message, e);
        }
    }

    /**
     * 简单的 Syslog 消息解析（RFC 3164 格式）
     */
    private SyslogMessage parseSyslogMessage(String message) {
        SyslogMessage syslogMsg = new SyslogMessage();

        // 尝试解析 PRI 部分
        if (message.startsWith("<")) {
            int priEnd = message.indexOf(">");
            if (priEnd > 0) {
                String priStr = message.substring(1, priEnd);
                try {
                    int pri = Integer.parseInt(priStr);
                    int facility = pri >> 3;
                    int severity = pri & 0x07;

                    syslogMsg.setFacility(facility);
                    syslogMsg.setSeverity(severity);

                    message = message.substring(priEnd + 1).trim();
                } catch (NumberFormatException e) {
                    // 忽略 PRI 解析错误
                }
            }
        }

        // 尝试解析时间戳和主机名
        // 这是一个简化的解析，实际实现可能需要更复杂的逻辑
        String[] parts = message.split(" ", 5);
        if (parts.length >= 4) {
            // 假设前三个部分是时间戳，第四个部分是主机名
            String timestamp = parts[0] + " " + parts[1] + " " + parts[2];
            syslogMsg.setTimestamp(timestamp);
            syslogMsg.setHostname(parts[3]);

            if (parts.length == 5) {
                syslogMsg.setMessage(parts[4]);
            }
        } else {
            syslogMsg.setMessage(message);
        }

        return syslogMsg;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("Exception in channel handler", cause);
        ctx.close();
    }
}