package com.caliverse.admin.scheduler.batch.service.impl;

import com.caliverse.admin.scheduler.batch.service.LogCompressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service
public class LogCompressServiceImpl implements LogCompressService {

    private static final String LOG_DIR = "..\\logs";
    private static final String LOG_FILE_PREFIX = "caliverse";

    @Override
    public void compressLastMonthLogs() {
        log.info("Start compressing last month's logs");
        try {
            LocalDate lastMonth = LocalDate.now().minusMonths(1);
            String yearMonth = lastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM"));

            String zipFileName = LOG_DIR + File.separator +
                    LOG_FILE_PREFIX + "_" + yearMonth + ".zip";

            String logFilePattern = LOG_FILE_PREFIX + "." + yearMonth + "*";

            try (FileOutputStream fos = new FileOutputStream(zipFileName);
                 ZipOutputStream zos = new ZipOutputStream(fos)) {

                Files.newDirectoryStream(Paths.get(LOG_DIR), logFilePattern)
                        .forEach(path -> {
                            try {
                                addToZipFile(path.toFile(), zos);
                                Files.delete(path);
                                log.info("Compressed and deleted file: {}", path.getFileName());
                            } catch (IOException e) {
                                log.error("Error while compressing file: {}", path.getFileName(), e);
                            }
                        });
            }
            log.info("Finished compressing last month's logs");
        } catch (IOException e) {
            log.error("Error in log compression service", e);
        }
    }

    private void addToZipFile(File file, ZipOutputStream zos) throws IOException {
        try (FileInputStream fis = new FileInputStream(file)) {
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zos.putNextEntry(zipEntry);

            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) >= 0) {
                zos.write(bytes, 0, length);
            }
            zos.closeEntry();
        }
    }
}
