package cn.pluss.platform.util;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.alibaba.fastjson.JSONObject;

public class CertFicatesUtils {

	//接口请求地址
	private static String requestUrl = "https://api.mch.weixin.qq.com/risk/getcertficates";
	//服务商号
	private static String mch_id = "1551169371";
	
	private static String payKey = "7F05NZBTJ3XNDK5HLSDC3H25ZXOQKDHT";
	
	
	//获取商户平台证书序列号
	public static String getCertFicates() {
		
		// 初始化一个HttpClient
		CloseableHttpClient httpClient = HttpClients.createDefault();
		// Post请求
		HttpPost httpPost = new HttpPost(requestUrl);
		/**
		 * 这边需要您提供微信分配的商户号跟API密钥
		 */
		Map<String, String> param = new HashMap<>(4);
		param.put("mch_id", mch_id);
		param.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
		// 暂只支持HMAC-SHA256 加密
		param.put("sign_type", "HMAC-SHA256");
		// 对你的参数进行加密处理
		String sign = WechatSignUtil.sha256Sign(param, payKey);
		param.put("sign", sign);
		httpPost.setEntity(new StringEntity(map2Xml(param), "UTF-8"));
		httpPost.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_XML.getMimeType());
		try {
			HttpResponse httpResponse = httpClient.execute(httpPost);

			if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
				String responseEntity = EntityUtils.toString(httpResponse.getEntity());
				System.out.println(responseEntity);
				Document document = DocumentHelper.parseText(responseEntity);
				Element root = document.getRootElement();
				if ("SUCCESS".equalsIgnoreCase(root.element("return_code").getTextTrim())&& "SUCCESS".equalsIgnoreCase(root.element("result_code").getTextTrim())) {
					
			
					//System.out.println(root.element("certificates").getTextTrim());
					JSONObject data = JSONObject.parseObject(root.element("certificates").getTextTrim());
					//System.out.println(data.getString("data"));
					JSONObject senconds = JSONObject.parseObject(data.getString("data").replace("[", "").replace("]", ""));
					JSONObject encrypt_certificate = JSONObject.parseObject(senconds.getString("encrypt_certificate"));
					
					
					
					return //senconds.getString("serial_no");
							//root.element("serial_no").getTextTrim();
							decryptCertSN(encrypt_certificate.getString("associated_data"),encrypt_certificate.getString("nonce"),encrypt_certificate.getString("ciphertext"),"VVGT43fzo4ICUGcH5jJ38VBGXwq8Kmja");
							//document.selectSingleNode("//certificates").getStringValue();
				}else {
					System.out.println("请求平台证书序号响应错误！");
				}
				// log.error("请求平台证书序号响应异常 {}",
				// document.selectSingleNode("//return_msg").getStringValue());
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
			// log.error("执行httpclient请求平台证书序号错误 {}", e);
		}
		return null;
	}

	/**
	 * map对象转xml
	 *
	 * @param map
	 * @return
	 */
	private static String map2Xml(Map<String, String> map) {
		StringBuilder result = new StringBuilder();
		result.append("<xml>");
		if (map != null && map.keySet().size() > 0) {
			map.forEach((key, value) -> {
				result.append("<" + key + "><![CDATA[");
				result.append(value);
				result.append("]]></" + key + ">");
			});
		}
		result.append("</xml>");
		return result.toString();
	}
	
	
	//解密平台证书
	private static String decryptCertSN(String associatedData, String nonce, String cipherText, String apiv3Key) throws Exception{
        final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(apiv3Key.getBytes(), "AES");
        GCMParameterSpec spec = new GCMParameterSpec(128, nonce.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        cipher.updateAAD(associatedData.getBytes());
        return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText)));
    }
	
	
	
}
