/**
 * @Date: 20241029
 * @Author: WANGKANG
 * @Blog: https://wangkang1717/github.io
 * @Email: 1686617586@qq.com
 * @Description: None
 * Copyright 2024 WANGKANG, All Rights Reserved.
 */


package com.taais.biz.utils;

import java.io.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    /**
     * 压缩指定文件夹中的所有文件
     *
     * @param sourceFolderPath 源文件夹路径
     * @param zipFilePath      生成的ZIP文件路径
     * @throws IOException 如果发生I/O错误
     */
    public static void zipFolderFiles(String sourceFolderPath, String zipFilePath) throws IOException {
        File sourceFolder = new File(sourceFolderPath);
        if (!sourceFolder.exists() || !sourceFolder.isDirectory()) {
            throw new IllegalArgumentException("Source folder does not exist or is not a directory: " + sourceFolderPath);
        }

        try (FileOutputStream fos = new FileOutputStream(zipFilePath); ZipOutputStream zos = new ZipOutputStream(fos)) {
            zipDirectory(sourceFolder, "", zos);
        }
    }

    private static void zipDirectory(File folder, String baseName, ZipOutputStream zos) throws IOException {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 递归处理子目录，更新基础名称
                    zipDirectory(file, baseName + file.getName() + File.separator, zos);
                } else {
                    // 压缩文件，使用基础名称作为路径
                    zipFile(file, baseName + file.getName(), zos);
                }
            }
        }
    }

    private static void zipFile(File file, String fileName, ZipOutputStream zos) throws IOException {
        try (FileInputStream fis = new FileInputStream(file)) {
            ZipEntry zipEntry = new ZipEntry(fileName);
            zos.putNextEntry(zipEntry);

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

    public static boolean unzip(String zipFilePath, String targetDirectory) {
        AtomicBoolean flag = new AtomicBoolean(true);
        try {
            // 创建目标目录
            File destDir = new File(targetDirectory);
            if (!destDir.exists()) {
                destDir.mkdirs();
            }

            // 创建ZipFile对象
            ZipFile zipFile = new ZipFile(zipFilePath);


            // 遍历ZIP文件中的所有条目
            zipFile.stream().forEach(entry -> {
                // System.out.println("解压文件: " + entry.getName());
                try {
                    String entryName = entry.getName();
                    File entryFile = new File(targetDirectory + File.separator + entryName);

                    // 如果是目录，创建目录
                    if (entry.isDirectory()) {
                        entryFile.mkdirs();
                    } else {
                        // 创建父目录
                        File parentDir = entryFile.getParentFile();
                        if (!parentDir.exists()) {
                            parentDir.mkdirs();
                        }
                        // 解压文件
                        try (InputStream inputStream = zipFile.getInputStream(entry); FileOutputStream outputStream = new FileOutputStream(entryFile)) {
                            byte[] buffer = new byte[1024];
                            int len;
                            while ((len = inputStream.read(buffer)) > 0) {
                                outputStream.write(buffer, 0, len);
                            }
                        }
                    }
                } catch (IOException e) {
                    flag.set(false);
                    e.printStackTrace();
                }
            });

            System.out.println("解压完成: " + targetDirectory);
        } catch (IOException e) {
            flag.set(false);
            e.printStackTrace();
        }
        return flag.get();
    }

    public static void main(String[] args) {
        try {
            zipFolderFiles("C:\\home\\ObjectDetection_Web\\upload\\2024\\10\\12\\dataset_20241012115340A001_to_infrared", "C:\\home\\ObjectDetection_Web\\upload\\2024\\10\\12\\dataset_20241012115340A001_to_infrared.zip");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
