package com.mcwl.web.controller.resource;

import com.mcwl.web.controller.common.OssUtil;
import org.springframework.mock.web.MockMultipartFile;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.AlgorithmParameters;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author DaiZibo
 * @date 2025/2/5
 * @apiNote
 */

public class Test {


    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final String TRANSFORMATION = "AES";
    private static final String KEY = "iamkeyeeddzasdfs";
    private static byte[] SAVED_IV; // 静态变量存储IV，确保解密时可访问
//    iv=gHauCGwTlX/mgXrvTUCifQ==, key=aWFta2V5ZWVkZHphc2Rmcw==

    public static void main(String[] args) throws Exception {
        // 示例：加密文件并获取密钥
        Map<String, String> stringStringMap = encryptFile("D:\\ASE\\encryption\\十二女花神   -1-5月花神_十二花神-上1.safetensors", "D:\\ASE\\decode\\加密文件2.safetensors");
//        System.out.println("-------------------"+keyBase64);
//        System.out.println("Encryption Key: " + keyBase64);
//
//        // 使用上面得到的密钥解密文件
//        decryptFile("C:\\Users\\Dzb\\Desktop\\a.enc", "D:\\ASE\\encryption\\解密测试文件3.txt","aWFta2V5ZWVkZHphc2Rmcw==","gHauCGwTlX/mgXrvTUCifQ==");

//        Map<String, String> stringStringMap = uploadEncryptedFileToOSS("D:\\ASE\\encryption\\测试文件1.txt", "encrypted-test-file1.enc");
//        System.out.println("-------------"+stringStringMap);

    }

    public static Map<String, String> encryptFile(String sourcePath, String encryptedPath) throws Exception {
        Cipher cipher = initCipher(Cipher.ENCRYPT_MODE);
        try (FileInputStream fis = new FileInputStream(sourcePath);
             FileOutputStream fos = new FileOutputStream(encryptedPath);
             CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
            byte[] buffer = new byte[1024];
            int read;
            while ((read = fis.read(buffer)) != -1) {
                cos.write(buffer, 0, read);
            }
        }
        System.out.println("加密完成");

        SecretKey secretKey = new SecretKeySpec(KEY.getBytes(), TRANSFORMATION);
        Map<String, String> result = new HashMap<>();
        result.put("key", Base64.getEncoder().encodeToString(secretKey.getEncoded()));
        result.put("iv", Base64.getEncoder().encodeToString(SAVED_IV));
        return result;
    }

//    public static void decryptFile(String encryptedPath, String decryptedPath, String keyBase64) throws Exception {
//        byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
//        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, TRANSFORMATION);
//        Cipher cipher = initCipher(Cipher.DECRYPT_MODE, secretKeySpec);
//
//        try (FileInputStream fis = new FileInputStream(encryptedPath);
//             CipherInputStream cis = new CipherInputStream(fis, cipher);
//             FileOutputStream fos = new FileOutputStream(decryptedPath)) {
//            byte[] buffer = new byte[1024];
//            int read;
//            while ((read = cis.read(buffer)) != -1) {
//                fos.write(buffer, 0, read);
//            }
//        }
//        System.out.println("解密完成");
//    }


    public static void decryptFile(String encryptedPath, String decryptedPath, String keyBase64, String ivBase64) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
        byte[] ivBytes = Base64.getDecoder().decode(ivBase64);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, TRANSFORMATION);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
        Cipher cipher = initCipher(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

        try (FileInputStream fis = new FileInputStream(encryptedPath);
             CipherInputStream cis = new CipherInputStream(fis, cipher);
             FileOutputStream fos = new FileOutputStream(decryptedPath)) {
            byte[] buffer = new byte[1024];
            int read;
            while ((read = cis.read(buffer)) != -1) {
                fos.write(buffer, 0, read);
            }
        }
        System.out.println("解密完成");
    }


//    private static Cipher initCipher(int mode) throws Exception {
////        return initCipher(mode, null);
////    }
////
////    private static Cipher initCipher(int mode, SecretKeySpec secretKeySpec) throws Exception {
////        Cipher cipher = Cipher.getInstance(ALGORITHM);
////        if (secretKeySpec == null) {
////            secretKeySpec = new SecretKeySpec(KEY.getBytes(), TRANSFORMATION);
////        }
////        if (mode == Cipher.ENCRYPT_MODE && SAVED_IV == null) {
////            cipher.init(mode, secretKeySpec);
////            AlgorithmParameters params = cipher.getParameters();
////            SAVED_IV = params.getParameterSpec(IvParameterSpec.class).getIV();
////            System.out.println("Generated IV: " + Base64.getEncoder().encodeToString(SAVED_IV));
////        } else {
////            cipher.init(mode, secretKeySpec, new IvParameterSpec(SAVED_IV));
////        }
////        return cipher;
////    }


    private static Cipher initCipher(int mode, SecretKeySpec secretKeySpec, IvParameterSpec ivParameterSpec) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        if (secretKeySpec == null){
            secretKeySpec = new SecretKeySpec(KEY.getBytes(), TRANSFORMATION);
        }
        if (mode == Cipher.ENCRYPT_MODE) {
            cipher.init(mode, secretKeySpec);
            AlgorithmParameters params = cipher.getParameters();
            SAVED_IV = params.getParameterSpec(IvParameterSpec.class).getIV();
            System.out.println("Generated IV: " + Base64.getEncoder().encodeToString(SAVED_IV));
        } else {
            cipher.init(mode, secretKeySpec, ivParameterSpec);
        }
        return cipher;
    }

    private static Cipher initCipher(int mode) throws Exception {
        return initCipher(mode, null, null);
    }

    private static Cipher initCipher(int mode, SecretKeySpec secretKeySpec) throws Exception {
        return initCipher(mode, secretKeySpec, null);
    }


    public static Map<String, String> uploadEncryptedFileToOSS(String sourcePath, String ossFileName) throws Exception {
        Cipher cipher = initCipher(Cipher.ENCRYPT_MODE);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (FileInputStream fis = new FileInputStream(sourcePath);
             CipherInputStream cis = new CipherInputStream(fis, cipher)) {
            byte[] buffer = new byte[1024];
            int read;
            while ((read = cis.read(buffer)) != -1) {
                bos.write(buffer, 0, read);
            }
        }
        System.out.println("加密完成");

        // 将加密后的字节数组转换为MultipartFile
        MockMultipartFile multipartFile = new MockMultipartFile(ossFileName, ossFileName, "application/octet-stream", bos.toByteArray());
        // 调用上传方法
        String uploadedUrl = OssUtil.uploadMultipartFile(multipartFile);

        Map<String, String> result = new HashMap<>();
        result.put("uploadedUrl", uploadedUrl);
        SecretKey secretKey = new SecretKeySpec(KEY.getBytes(), TRANSFORMATION);

        result.put("key",Base64.getEncoder().encodeToString(secretKey.getEncoded()));
        result.put("iv", Base64.getEncoder().encodeToString(SAVED_IV));
        return result;
    }
}
