package com.om.utils;

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class FileSigner {

    private static final String PRIVATE_KEY_PATH = "/usr/local/docker/opera/static/private_key.pem"; // 私钥文件路径
   // private static final String PRIVATE_KEY_PATH = "B:\\WorkSpace\\PracticalRojects\\OperationSystem\\src\\main\\resources\\template\\static\\private_key.pem"; // 私钥文件路径


    public static MultipartFile sign(MultipartFile file) throws Exception {
        // 加载私钥
        PrivateKey privateKey = null;
        try {
             privateKey = loadPrivateKey(PRIVATE_KEY_PATH);
        }catch (Exception e){
            System.out.println("-----------------------------------");
            e.printStackTrace();
        }
        // 读取待签名文件内容
        byte[] fileContent = file.getBytes();

        // 使用SHA256withRSA算法签名文件
        Signature signer = Signature.getInstance("SHA256withRSA");
        signer.initSign(privateKey);
        signer.update(fileContent);
        byte[] signature = signer.sign();

        // 将签名信息拼接到文件内容中
        byte[] lengthBytes = intToByteArray(signature.length);
        byte[] concatenated = concatenate(lengthBytes, signature);
        byte[] signedFileContent = concatenate(concatenated, fileContent);

        // 创建一个新的 MultipartFile 对象来代表签名后的文件
        MultipartFile signedFile = new MockMultipartFile(
                file.getName(), file.getOriginalFilename(), file.getContentType(), signedFileContent);

        System.out.println("File signed successfully!");

        return signedFile;
    }


    private static PrivateKey loadPrivateKey(String keyPath) throws Exception {
        // 这里是简化代码，实际中你可能需要使用PEM解析器来加载私钥  
        // 这里假设私钥是PKCS#8格式，并且没有密码保护  
        String privateKeyContent = new String(Files.readAllBytes(Paths.get(keyPath)));
        privateKeyContent = privateKeyContent.replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s", "");

        byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(privateKeyContent);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
        return keyFactory.generatePrivate(keySpec);
    }

    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    public static String bytesToHexString(byte[] src, int nLen) {
        return bytesToHexString( src, 0, nLen);
    }


    public static String bytesToHexString(byte[] src, int offset, int nLen) {
        StringBuilder stringBuilder = new StringBuilder("");

        if (src == null || src.length <= 0 || nLen <= 0) {
            return "";
        }
        for (int i = offset; (i+offset) < src.length && i < nLen; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v).toUpperCase();
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
            stringBuilder.append(' ');
        }
        return stringBuilder.toString();
    }


    public static byte[] concatenate(byte[] first, byte[] second) {
        byte[] result = new byte[first.length + second.length];
        System.arraycopy(first, 0, result, 0, first.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }


}