package cn.pluss.platform.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.Map;
import java.util.Properties;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

public class WXPayHttpUtil {

  private static final String UTFCHARSET = "UTF-8";
  private static final String XMLCONTENT = "text/xml;charset=utf-8";
  private static final String FORMCONTENT = "multipart/form-data;charset=utf-8";

  /**
   * 不需证书上传xml形式接口
   * @param url   接口地址
   * @param reqDataTo  请求参数
   * @return
   */
  public static String WXHttpPostXMLWithoutCert(
    String url,
    Map<String, String> reqDataTo
  ) {
    HttpPost httpPost = new HttpPost(url);
    StringEntity postEntity = new StringEntity(
      WXPayXmlUtil.parseMapToXML(reqDataTo),
      UTFCHARSET
    );
    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, XMLCONTENT);
    httpPost.setEntity(postEntity);
    StringBuilder stringBuilder = new StringBuilder();
    try (
      CloseableHttpClient client = HttpClients.createDefault();
      CloseableHttpResponse response = client.execute(httpPost);
    ) {
      if (response != null && response.getEntity() != null) {
        HttpEntity entity = response.getEntity();
        try (
          InputStream in = entity.getContent();
          BufferedReader reader = new BufferedReader(
            new InputStreamReader(in, "UTF-8")
          )
        ) {
          reader
            .lines()
            .forEach(
              line -> {
                stringBuilder.append(line);
              }
            );
        }
      }
    } catch (IOException e) {
      //LOGGER.debug(e.getMessage());
      return "";
    }
    return stringBuilder.toString();
  }

  /**
   * 需证书上传xml形式接口
   * @param url 接口地址
   * @param reqData 参数
   * @param certPath 证书文件位置 (服务商)
   * @return
   */
  public static String WXHttpPostXMLWithCert(
    String url,
    Map<String, String> reqData,
    String certPath
  ) {
    HttpPost queryState = new HttpPost(url);
    SSLConnectionSocketFactory sslsf = null;
    //读取本机存放的PKCS12证书文件
    try (
      InputStream inputStream = Thread
        .currentThread()
        .getContextClassLoader()
        .getResourceAsStream("apiclient_cert.p12")
    ) {
      //指定读取证书格式为PKCS12
      KeyStore keyStore = KeyStore.getInstance("PKCS12");
      //"100000"为密码即商户号
      keyStore.load(inputStream, reqData.get("mch_id").toCharArray());
      SSLContext sslcontext = SSLContexts
        .custom()
        .loadKeyMaterial(keyStore, reqData.get("mch_id").toCharArray())
        .build();
      sslsf =
        new SSLConnectionSocketFactory(
          sslcontext,
          new String[] { "TLSv1" },
          null,
          new DefaultHostnameVerifier()
        );
    } catch (Exception e) {
      return "";
    }
    StringBuilder stringBuilder = new StringBuilder();
    StringEntity postEntity = new StringEntity(
      WXPayXmlUtil.parseMapToXML(reqData),
      "UTF-8"
    );
    queryState.setEntity(postEntity);
    queryState.setHeader(HttpHeaders.CONTENT_TYPE, XMLCONTENT);
    try (
      CloseableHttpClient client = HttpClients
        .custom()
        .setSSLSocketFactory(sslsf)
        .build();
      CloseableHttpResponse response = client.execute(queryState);
    ) {
      if (response != null && response.getEntity() != null) {
        HttpEntity entity = response.getEntity();
        try (
          InputStream in = entity.getContent();
          BufferedReader reader = new BufferedReader(
            new InputStreamReader(in, "UTF-8")
          )
        ) {
          reader
            .lines()
            .forEach(
              line -> {
                stringBuilder.append(line);
              }
            );
        }
      }
    } catch (IOException e) {
      //LOGGER.debug(e.getMessage());
      return "";
    }
    return stringBuilder.toString();
  }

  /**
   * 需证书上传xml形式接口
   * @param url 接口地址
   * @param reqData 参数
   * @param certPath 证书文件位置 (普通商户)
   * @return
   */
  public static String WXHttpPostXMLWithCertOrdinary(
    String url,
    Map<String, String> reqData,
    String certPath
  ) {
    HttpPost queryState = new HttpPost(url);
    SSLConnectionSocketFactory sslsf = null;
    //读取本机存放的PKCS12证书文件
    try (
      InputStream inputStream = Thread
        .currentThread()
        .getContextClassLoader()
        .getResourceAsStream("apiclient_cert1.p12")
    ) {
      //指定读取证书格式为PKCS12
      KeyStore keyStore = KeyStore.getInstance("PKCS12");
      //"100000"为密码即商户号
      keyStore.load(inputStream, reqData.get("mch_id").toCharArray());
      SSLContext sslcontext = SSLContexts
        .custom()
        .loadKeyMaterial(keyStore, reqData.get("mch_id").toCharArray())
        .build();
      sslsf =
        new SSLConnectionSocketFactory(
          sslcontext,
          new String[] { "TLSv1" },
          null,
          new DefaultHostnameVerifier()
        );
    } catch (Exception e) {
      return "";
    }
    StringBuilder stringBuilder = new StringBuilder();
    StringEntity postEntity = new StringEntity(
      WXPayXmlUtil.parseMapToXML(reqData),
      "UTF-8"
    );
    queryState.setEntity(postEntity);
    queryState.setHeader(HttpHeaders.CONTENT_TYPE, XMLCONTENT);
    try (
      CloseableHttpClient client = HttpClients
        .custom()
        .setSSLSocketFactory(sslsf)
        .build();
      CloseableHttpResponse response = client.execute(queryState);
    ) {
      if (response != null && response.getEntity() != null) {
        HttpEntity entity = response.getEntity();
        try (
          InputStream in = entity.getContent();
          BufferedReader reader = new BufferedReader(
            new InputStreamReader(in, "UTF-8")
          )
        ) {
          reader
            .lines()
            .forEach(
              line -> {
                stringBuilder.append(line);
              }
            );
        }
      }
    } catch (IOException e) {
      //LOGGER.debug(e.getMessage());
      return "";
    }
    return stringBuilder.toString();
  }
}
