package com.sunyard.ssp.modules.monitor.log.serviceimpl;

import com.sunyard.ssp.modules.monitor.log.service.LogDownloadService;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class LogDownloadServiceImpl implements LogDownloadService {

    private static final String LOG_BASE_PATH = "logs/";
    private static final DateTimeFormatter folderFormatter = DateTimeFormatter.ofPattern("yyyy-MM"); // 用于遍历月份的目录格式
    private static final DateTimeFormatter fileFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 用于解析文件名中的日期格式

    /**
     * 下载指定日期范围内的日志文件为ZIP格式。
     *
     * @param startDate 开始日期（包含）
     * @param endDate 结束日期（包含）
     * @return 包含所选日志文件的ByteArrayResource对象
     * @throws IOException 如果读取文件或创建ZIP时发生IO错误
     */
    @Override
    public ByteArrayResource downloadLogsAsZip(LocalDate startDate, LocalDate endDate) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (ZipOutputStream zos = new ZipOutputStream(baos)) {
            // 遍历指定日期范围内的每个月份
            for (LocalDate date = startDate.withDayOfMonth(1); !date.isAfter(endDate); date = date.plusMonths(1)) {
                Files.list(Paths.get(LOG_BASE_PATH, folderFormatter.format(date)))
                        .filter(path -> isRelevantLogFile(path, startDate, endDate))
                        .forEach(path -> {
                            ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
                            try {
                                zos.putNextEntry(zipEntry);
                                Files.copy(path, zos);
                                zos.closeEntry();
                            } catch (IOException e) {
                                throw new RuntimeException("压缩日志文件时发生错误", e);
                            }
                        });
            }
            zos.finish();
        }
        return new ByteArrayResource(baos.toByteArray(), "logs.zip");
    }

    /**
     * 判断给定路径是否是指定日期范围内的相关日志文件。
     *
     * @param path 文件路径
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 如果文件在指定日期范围内则返回true，否则返回false
     */
    private boolean isRelevantLogFile(Path path, LocalDate startDate, LocalDate endDate) {
        String fileName = path.getFileName().toString();
        if (!fileName.endsWith(".log")) {
            return false;
        }

        // 解析文件名中的日期
        String dateString = fileName.substring("sspweb-DEBUG-".length(), fileName.indexOf('_', "sspweb-DEBUG-".length()));
        LocalDate fileDate;
        try {
            fileDate = LocalDate.parse(dateString, fileFormatter);
        } catch (Exception e) {
            // 如果无法解析日期，忽略该文件
            return false;
        }

        // 检查文件日期是否在指定范围内
        return !fileDate.isBefore(startDate) && !fileDate.isAfter(endDate);
    }
}