/**
 * @ProjectName: 智慧评标-主观分助手
 * @Package: com.zhpb.gdyd_zhpb_zgf.config
 * @ClassName: SystemOutInterceptor
 * @Description: 拦截System.out.println输出，保存到数据库
 * @Author: 张志锋
 * @Date: 2025-10-31
 * @Version: 1.0
 * @Copyright: © 2025 智慧评标-主观分助手
 */
package com.zhpb.gdyd_zhpb_zgf.config;

import com.zhpb.gdyd_zhpb_zgf.entity.mysql.SysLog;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.SysLogRepository;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.time.LocalDateTime;

/**
 * System.out拦截器
 */
@Component
public class SystemOutInterceptor {

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

    @Autowired
    private SysLogRepository sysLogRepository;

    @Value("${spring.application.name:gdyd_zhpb_zgf}")
    private String applicationName;

    @PostConstruct
    public void init() {
        // 创建拦截输出流
        try {
            PrintStream originalOut = System.out;
            PrintStream originalErr = System.err;
            
            System.setOut(new PrintStream(new DatabasePrintStream(originalOut, "OUT", false), true, "UTF-8"));
            System.setErr(new PrintStream(new DatabasePrintStream(originalErr, "ERR", true), true, "UTF-8"));
            logger.info("System.out和System.err拦截器已启动");
        } catch (Exception e) {
            logger.error("启动System.out拦截器失败", e);
        }
    }

    /**
     * 自定义打印流，同时输出到原流和数据库
     */
    private class DatabasePrintStream extends ByteArrayOutputStream {
        private final PrintStream original;
        private final String type;
        private final boolean isError;

        public DatabasePrintStream(PrintStream original, String type, boolean isError) {
            this.original = original;
            this.type = type;
            this.isError = isError;
        }

        @Override
        public synchronized void write(byte[] b, int off, int len) {
            super.write(b, off, len);
            original.write(b, off, len);
        }

        @Override
        public synchronized void write(int b) {
            super.write(b);
            original.write(b);
        }

        @Override
        public synchronized void flush() {
            try {
                super.flush();
                original.flush();
                saveToDatabase();
            } catch (Exception e) {
                // 忽略异常，确保不影响正常输出
            }
        }

        private void saveToDatabase() {
            try {
                String content = new String(toByteArray(), Charset.forName("UTF-8"));
                if (content != null && !content.trim().isEmpty()) {
                    // 清除缓冲区
                    reset();

                    // 过滤掉不需要记录的日志
                    if (shouldSkip(content)) {
                        return;
                    }

                    // 将多行内容合并为一行（替换换行符为空格）
                    String singleLine = content.replace("\n", " ").replace("\r", " ").trim();
                    
                    if (singleLine.isEmpty()) {
                        return;
                    }

                    SysLog sysLog = new SysLog();
                    sysLog.setLogLevel(isError ? "ERROR" : "OUT");
                    sysLog.setLoggerName("SYSTEM_" + type);
                    sysLog.setLogContent(singleLine);
                    sysLog.setFullMessage("[" + type + "] " + singleLine);
                    sysLog.setThreadName(Thread.currentThread().getName());
                    sysLog.setCreateTime(LocalDateTime.now());
                    sysLog.setApplicationName(applicationName);

                    // 异步保存
                    final SysLog finalLog = sysLog;
                    new Thread(() -> {
                        try {
                            sysLogRepository.save(finalLog);
                        } catch (Exception e) {
                            // 忽略保存失败，避免循环
                        }
                    }).start();
                }
            } catch (Exception e) {
                // 忽略异常，确保不影响正常输出
            }
        }

        /**
         * 判断是否应该跳过该日志
         */
        private boolean shouldSkip(String content) {
            if (content == null || content.trim().isEmpty()) {
                return true;
            }
            
            String lowerContent = content.toLowerCase();
            
            // 跳过SQL语句
            if (lowerContent.contains("hibernate:") || 
                lowerContent.contains("select ") || 
                lowerContent.contains("insert ") || 
                lowerContent.contains("update ") || 
                lowerContent.contains("delete ") ||
                lowerContent.contains("create table") ||
                lowerContent.contains("alter table") ||
                lowerContent.contains("drop table")) {
                return true;
            }
            
            // 跳过Spring Boot启动相关日志
            if (lowerContent.contains("started gdydzhpbzgfapplication") ||
                lowerContent.contains("spring application startup") ||
                lowerContent.contains("beanfactory") ||
                lowerContent.contains("obtaining singleton bean") ||
                lowerContent.contains("autowired annotation") ||
                lowerContent.contains("initialized jpa entitymanagerfactory") ||
                lowerContent.contains("hibernate is in classpath") ||
                lowerContent.contains("creating shared instance") ||
                lowerContent.startsWith("http://127.0.0.1:")) {
                return true;
            }
            
            // 跳过Hibernate相关日志
            if (lowerContent.contains("hibernate") && 
                (lowerContent.contains("dialect") || 
                 lowerContent.contains("sessionfactory") ||
                 lowerContent.contains("entitymanagerfactory"))) {
                return true;
            }
            
            return false;
        }

        @Override
        public void close() {
            try {
                flush();
                super.close();
            } catch (Exception e) {
                // 忽略异常
            }
        }
    }
}

