package com.backendsys.service.KeyPair;

import com.backendsys.entity.KeyPair.KeyPairDTO;
import com.backendsys.exception.CustException;
import org.springframework.stereotype.Service;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Service
public class KeyPairServiceImpl implements KeyPairService{

    /**
     * 获得密钥对（公钥、私钥）
     */
    @Override
    public KeyPairDTO generateKeyPair() {
        KeyPairDTO keyPairDTO = new KeyPairDTO();
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048); // 可以选择密钥长度，如1024, 2048等
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
            // 将公钥转换为 Base64 编码的字符串
            String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
            String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());

            keyPairDTO.setPublic_key(publicKeyString);
            keyPairDTO.setPrivate_key(privateKeyString);
        } catch (NoSuchAlgorithmException e) {
            throw new CustException(e.getMessage());
        }
        return keyPairDTO;
    }

    /**
     * (公钥) 将 Base64 转回 Byte
     */
    public PublicKey getPublicBase64ToByte(String public_key_str) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(public_key_str);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            PublicKey publicKeyRecovered = keyFactory.generatePublic(keySpec);
            return publicKeyRecovered;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new CustException(e.getMessage());
        }
    }
    /**
     * (私钥) 将 Base64 转回 Byte
     */
    public PrivateKey getPrivateBase64ToByte(String private_key_str) {
        try {
            byte[] keyBytes = Base64.getDecoder().decode(private_key_str);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            PrivateKey privateKeyRecovered = keyFactory.generatePrivate(keySpec);
            return privateKeyRecovered;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new CustException(e.getMessage());
        }
    }

    /**
     * 使用公钥来加密数据
     */
    public String encryptedRSA(PublicKey publicKey, String content) {
        try {
            // 使用公钥来加密数据
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedData = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            // 将加密后的字节数组转换为 Base64 编码
            String encryptedString = Base64.getEncoder().encodeToString(encryptedData);
            return encryptedString;
        } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            throw new CustException(e.getMessage());
        }
    }

    /**
     * 使用私钥来解密数据
     */
    public String decryptedRSA(PrivateKey privateKey, String content_encrypted) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // Base64 解码得到加密的数据字节序列
            byte[] encryptedDataBytes = Base64.getDecoder().decode(content_encrypted);
            byte[] decryptedData = cipher.doFinal(encryptedDataBytes);
            String decryptedString = new String(decryptedData);
            return decryptedString;
        } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            throw new CustException(e.getMessage());
        }
    }



}
