package com.zsElectric.boot.system.quartz;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.stream.Stream;

/**
 * 日志文件清理定时任务
 * 定期清理超过指定天数的历史日志文件
 *
 * @author zsElectric
 * @since 2026-01-06
 */
@Slf4j
@Component
public class LogCleanupJob {

    @Value("${spring.application.name:zsElectric-boot}")
    private String appName;

    /**
     * 日志保留天数
     */
    private static final int LOG_RETENTION_DAYS = 30;

    /**
     * 日志目录
     */
    private static final String LOG_BASE_PATH = "/logs";

    /**
     * 每天凌晨3点执行一次
     * 清理超过30天的日志文件
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void cleanupExpiredLogs() {
        log.info("开始执行日志清理任务，清理{}天前的日志文件", LOG_RETENTION_DAYS);

        Path logDir = Paths.get(LOG_BASE_PATH, appName);

        if (!Files.exists(logDir)) {
            log.warn("日志目录不存在: {}", logDir);
            return;
        }

        Instant cutoffTime = Instant.now().minus(LOG_RETENTION_DAYS, ChronoUnit.DAYS);
        int deletedCount = 0;
        int failedCount = 0;

        try (Stream<Path> files = Files.list(logDir)) {
            for (Path file : (Iterable<Path>) files::iterator) {
                // 只处理 .log 文件，跳过当前正在写入的日志文件
                String fileName = file.getFileName().toString();
                if (!fileName.endsWith(".log") || fileName.equals("log.log")) {
                    continue;
                }

                try {
                    BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
                    Instant lastModified = attrs.lastModifiedTime().toInstant();

                    if (lastModified.isBefore(cutoffTime)) {
                        Files.delete(file);
                        deletedCount++;
                        log.debug("已删除过期日志文件: {}", fileName);
                    }
                } catch (IOException e) {
                    failedCount++;
                    log.error("删除日志文件失败: {}", fileName, e);
                }
            }
        } catch (IOException e) {
            log.error("读取日志目录失败: {}", logDir, e);
        }

        log.info("日志清理任务执行完成，成功删除{}个文件，失败{}个", deletedCount, failedCount);
    }
}
