package com.rf.psychological.wxpay.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

/**
 * @Description:读取微信支付配置文件
 * @Author: zsf
 * @Date: 2022/6/21
 */
@Configuration
//@PropertySource("classpath:config/wxpay.properties")
@ConfigurationProperties(prefix = "wx.pay")
//@Profile(value = "!lan")
@ConditionalOnProperty(prefix="wx.pay",name = "is_lan", havingValue = "false")
@Data
@Slf4j
public class WxPayConfig {
    //商户号
    private String mchId;

    //商户api证书序列号
    private String mchSerialNo;

    //商户私钥文件
    private String privateKeyPath;

    //API秘钥
    private String apiV3Key;

    //APPID
    private String appId;

    //微信服务器地址
    private String domain;

    //接受结果回调地址
    private String notifyDomain;

    //ASPI秘钥
    private String aspi_secret;

    //code2openid url
    private String aspi_url;

    //ASPI APPID
    private String aspi_appid;

    /**
     * 获取商户的私钥文件
     * @param fileName
     * @return
     */
    public PrivateKey getPrivateKey(String fileName){
        try {
            String path =  this.getClass().getClassLoader().getResource(fileName).getPath();
            InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName);
            log.info(path);
            return PemUtil.loadPrivateKey(is);//new ByteArrayInputStream(fileName.getBytes("utf-8"))
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("私钥文件不存在",e);
        }
    }

    /**
     * 获取签名验证器
     * @return
     */
    @Bean
    Verifier getVerifier() {
        try {
            log.info("获取证书管理器实例");
            // 获取证书管理器实例
            CertificatesManager   certificatesManager = CertificatesManager.getInstance();
           // log.info("向证书管理器增加需要自动更新平台证书的商户信息");
            // 向证书管理器增加需要自动更新平台证书的商户信息
            //获取商户私钥
            PrivateKey privateKey = getPrivateKey(privateKeyPath);
            //log.info("获取商户私钥");
            //私钥签名对象
            PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);
            //log.info("私钥签名对象");
            //身份认证对象
            WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
            //log.info("身份认证对象");
            certificatesManager.putMerchant(mchId,wechatPay2Credentials, apiV3Key.getBytes(StandardCharsets.UTF_8));
            //log.info("从证书管理器中获取verifier");
            // 从证书管理器中获取verifier
            Verifier verifier = certificatesManager.getVerifier(mchId);
            return  verifier;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 获取http请求对象
     * @param verifier
     * @return
     */
    @Bean(name = "wxPayClient")
    public CloseableHttpClient getWxPayClient(Verifier verifier){
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, getPrivateKey(privateKeyPath))
                .withValidator(new WechatPay2Validator(verifier));
        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
        return builder.build();
    }
}
