package com.common.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.common.entity.*;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

@Service
public class SyslogService {

    private static final Logger logger = LoggerFactory.getLogger(SyslogService.class);

    /**
     * 发送syslog消息
     */
    public boolean sendSyslogMessage(SyslogRequest request) {
        logger.info("开始发送syslog消息: IP={}, Port={}", request.getIp(), request.getPort());

        try {
            //String syslogMessage = formatSyslogMessage(request);
            String syslogMessage =request.getLogContent();
                    logger.debug("传入的syslog消息: {}", syslogMessage);

            if ("UDP".equalsIgnoreCase(request.getProtocol())) {
                return sendUdpSyslog(request.getIp(), request.getPort(), syslogMessage);
            } else {
                return sendTcpSyslog(request.getIp(), request.getPort(), syslogMessage);
            }

        } catch (Exception e) {
            logger.error("发送syslog消息失败", e);
            return false;
        }
    }

    /**
     * 格式化syslog消息
     */
    private String formatSyslogMessage(SyslogRequest request) {
        // 计算PRI值 (Facility * 8 + Severity)
        int pri = calculatePri(request.getFacility(), request.getSeverity());

        // 时间戳
        String timestamp = new SimpleDateFormat("MMM dd HH:mm:ss").format(new Date());

        // 主机名
        String hostname = "myapp";

        // 构建syslog消息
        return String.format("<%d>%s %s %s", pri, timestamp, hostname, request.getLogContent());
    }

    /**
     * 计算PRI值
     */
    private int calculatePri(String facility, String severity) {
        int facilityValue = getFacilityValue(facility);
        int severityValue = getSeverityValue(severity);
        return facilityValue * 8 + severityValue;
    }

    private int getFacilityValue(String facility) {
        switch (facility.toUpperCase()) {
            case "KERN": return 0;
            case "USER": return 1;
            case "MAIL": return 2;
            case "DAEMON": return 3;
            case "AUTH": return 4;
            case "SYSLOG": return 5;
            case "LPR": return 6;
            case "NEWS": return 7;
            case "UUCP": return 8;
            case "CRON": return 9;
            case "AUTHPRIV": return 10;
            case "FTP": return 11;
            case "LOCAL0": return 16;
            case "LOCAL1": return 17;
            case "LOCAL2": return 18;
            case "LOCAL3": return 19;
            case "LOCAL4": return 20;
            case "LOCAL5": return 21;
            case "LOCAL6": return 22;
            case "LOCAL7": return 23;
            default: return 1; // 默认USER
        }
    }

    private int getSeverityValue(String severity) {
        switch (severity.toUpperCase()) {
            case "EMERG": return 0;
            case "ALERT": return 1;
            case "CRIT": return 2;
            case "ERR": return 3;
            case "WARNING": return 4;
            case "NOTICE": return 5;
            case "INFO": return 6;
            case "DEBUG": return 7;
            default: return 6; // 默认INFO
        }
    }

    /**
     * 通过UDP发送syslog消息
     */
    private boolean sendUdpSyslog(String ip, int port, String message) {
        try (DatagramSocket socket = new DatagramSocket()) {
            InetAddress address = InetAddress.getByName(ip);
            byte[] buffer = message.getBytes();
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
            socket.send(packet);
            logger.info("Syslog消息发送成功");
            return true;
        } catch (SocketException e) {
            logger.error("创建Socket失败", e);
            return false;
        } catch (IOException e) {
            logger.error("发送数据失败", e);
            return false;
        }
    }

    /**
     * 通过TCP发送syslog消息
     */
    private boolean sendTcpSyslog(String ip, int port, String message) {
        Socket socket = null;
        OutputStream outputStream = null;

        try {
            // 创建TCP socket连接
            socket = new Socket(ip, port);

            // 设置连接超时和读取超时（可选）
            socket.setSoTimeout(5000); // 5秒超时

            // 获取输出流
            outputStream = socket.getOutputStream();

            // 发送消息，TCP通常需要以换行符结束
            byte[] buffer = (message + "\n").getBytes();
            outputStream.write(buffer);
            outputStream.flush(); // 确保数据发送

            logger.info("TCP Syslog消息发送成功: {}:{}", ip, port);
            return true;

        } catch (UnknownHostException e) {
            logger.error("无法解析主机地址: {}", ip, e);
            return false;
        } catch (IOException e) {
            logger.error("TCP连接或发送数据失败: {}:{}", ip, port, e);
            return false;
        } finally {
            // 关闭资源
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    logger.warn("关闭输出流时发生异常", e);
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    logger.warn("关闭socket时发生异常", e);
                }
            }
        }
    }
}