package com.ruoyi.common.core.utils.file;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.io.inputstream.ZipInputStream;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.List;
import java.util.Map;

public class ZipUtils {
    public static void zip(String filePath, String toFilePath, String password) throws Exception {
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(EncryptionMethod.AES);
        // Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
        zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);


        File file = new File(filePath);

        ZipFile zipFile = new ZipFile(toFilePath, password.toCharArray());
        zipFile.addFile(file, zipParameters);
    }

    /**
     * 将对象或对象数组转成json字符串输出到zip并存储
     * @param json 对象或对象数组
     * @param entryName zip内文件名
     * @param toFilePath 保存文件路径
     * @param password zip密码
     */
    public static void jsonZip(Object json, String entryName, String toFilePath, String password) {
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(EncryptionMethod.AES);
        // Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
        zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
        zipParameters.setFileNameInZip(entryName);
        ZipFile zipFile = new ZipFile(toFilePath, password.toCharArray());
        ObjectMapper mapper = new ObjectMapper();
        try {
            zipFile.addStream(new ByteArrayInputStream(mapper.writer().writeValueAsBytes(json)), zipParameters);
        } catch (ZipException | JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 从打包文件读取加密json数据并转list
     * @param file 读取文件
     * @param password 密码
     * @throws Exception
     */
    public static List<Map<String,Object>> readZipFileToList(String file, String password) throws Exception {
        ZipFile zipFile = new ZipFile(file);
        if (!zipFile.isValidZipFile()) {
            return null;
        }
        //检查是否需要密码
        if (zipFile.isEncrypted()) {
            zipFile.setPassword(password.toCharArray());
        }
        // 获取ZIP中所有文件的FileHeader，以便后面对zip中文件进行遍历
        List<FileHeader> list = zipFile.getFileHeaders();
        List<Map<String,Object>> hashMap = null;
        // 遍历其中的文件
        for (FileHeader fileHeader : list) {
            ZipInputStream inputStream = zipFile.getInputStream(fileHeader);
            ObjectMapper objectMapper = new ObjectMapper();
            hashMap = objectMapper.readValue(inputStream, List.class);
        }
        return hashMap;
    }
}
