package ink.wgink.module.wechat.pay.utils.v3;

import ink.wgink.interfaces.consts.ISystemConstant;
import org.bouncycastle.util.encoders.Base64;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * @ClassName: PayPrivateKeyUtil
 * @Description: 商户私钥工具
 * @Author: wanggeng
 * @Date: 2021/8/18 8:43 下午
 * @Version: 1.0
 */
public class PayPrivateKeyUtil {

    /**
     * 算法
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 获取商户私钥
     *
     * @param keyPath 商户私钥证书路径
     * @return 商户私钥
     * @throws Exception 解析 key 异常
     */
    public static String getPrivateKey(String keyPath) throws Exception {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(keyPath));
        StringBuilder apiClientKeySB = new StringBuilder();
        for (String line; (line = bufferedReader.readLine()) != null; ) {
            apiClientKeySB.append(line);
        }
        String originalKey = apiClientKeySB.toString();
        String privateKey = originalKey
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");
        return PayPrivateKeyUtil.getPrivateKeyStr(PayPrivateKeyUtil.loadPrivateKey(privateKey));
    }


    /**
     * 私钥字符串
     *
     * @param privateKey
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getPrivateKeyStr(PrivateKey privateKey) throws UnsupportedEncodingException {
        return new String(Base64.encode(privateKey.getEncoded()), ISystemConstant.CHARSET_UTF8);
    }


    /**
     * 从字符串中加载私钥
     *
     * @param privateKeyStr 私钥
     * @return {@link PrivateKey}
     * @throws Exception 异常信息
     */
    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
        try {
            byte[] buffer = Base64.decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            return keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("私钥非法");
        } catch (NullPointerException e) {
            throw new Exception("私钥数据为空");
        }
    }

    /**
     * 私钥签名
     *
     * @param data       需要加密的数据
     * @param privateKey 私钥
     * @return 加密后的数据
     * @throws Exception 异常信息
     */
    public static String encryptByPrivateKey(String data, String privateKey) throws Exception {
        PKCS8EncodedKeySpec priPkcs8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(priPkcs8);
        Signature signature = Signature.getInstance("SHA256WithRSA");

        signature.initSign(priKey);
        signature.update(data.getBytes(StandardCharsets.UTF_8));
        byte[] signed = signature.sign();
        return new String(Base64.encode(signed), ISystemConstant.CHARSET_UTF8);
    }


}
