package com.mmc.csf.common.util.web;

import org.apache.commons.codec.binary.Base64;

import javax.net.ssl.*;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;

/**
 * @author 作者 geDuo
 * @version 创建时间：2021年9月1日 下午3:56:37
 * @explain 类说明
 */
public class HttpsRequestUtil {
    public static String httpsRequest(String url, String method, Map<String, String> headerMap, String bodyData)
            throws Exception {
        HttpsURLConnection conn = null;
        OutputStream out = null;
        String rsp = null;
        byte[] byteArray = bodyData.getBytes("utf-8");
        try {
            URL uri = new URL(url);
            conn = (HttpsURLConnection) uri.openConnection();
            // 忽略证书验证--Begin
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            // 忽略证书验证--End
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestProperty("Host", uri.getHost());
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            if (headerMap != null) {
                Iterator<Map.Entry<String, String>> it = headerMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, String> entry = it.next();
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            out = conn.getOutputStream();
            out.write(byteArray);
            out.close();

            if (conn.getResponseCode() == 200) {
                rsp = getStreamAsString(conn.getInputStream(), "utf-8");
            } else {
                rsp = getStreamAsString(conn.getErrorStream(), "utf-8");
            }
        } catch (Exception e) {
            if (null != out) {
                out.close();
            }
            e.printStackTrace();
        }
        return rsp;
    }

    /**
     * 获取小程序二维码
     *
     * @param url
     * @param method
     * @param headerMap
     * @param bodyData
     * @return
     * @throws Exception
     */
    public static String getACodeBase64(String url, String method, Map<String, String> headerMap, String bodyData)
            throws Exception {
        HttpsURLConnection conn = null;
        OutputStream out = null;
        String rsp = null;
        byte[] byteArray = bodyData.getBytes("utf-8");
        try {
            URL uri = new URL(url);
            conn = (HttpsURLConnection) uri.openConnection();
            // 忽略证书验证--Begin
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            // 忽略证书验证--End
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestProperty("Host", uri.getHost());
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            if (headerMap != null) {
                Iterator<Map.Entry<String, String>> it = headerMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, String> entry = it.next();
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            out = conn.getOutputStream();
            out.write(byteArray);
            out.close();

            if (conn.getResponseCode() == 200) {
                byte[] bytes = InputStreamToByte(conn.getInputStream());
                rsp = Base64.encodeBase64String(bytes);
            } else {
                rsp = getStreamAsString(conn.getErrorStream(), "utf-8");
            }
        } catch (Exception e) {
            if (null != out) {
                out.close();
            }
            e.printStackTrace();
        }
        return rsp;
    }

    /**
     * 输入流转字节流
     */
    private static byte[] InputStreamToByte(InputStream in) throws IOException {
        ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int ch;
        while ((ch = in.read(buffer)) != -1) {
            bytestream.write(buffer, 0, ch);
        }
        byte data[] = bytestream.toByteArray();
        bytestream.close();
        return data;
    }

    private static String getStreamAsString(InputStream stream, String charset) throws IOException {
        try {
            Reader reader = new InputStreamReader(stream, charset);
            StringBuilder response = new StringBuilder();

            final char[] buff = new char[1024];
            int read = 0;
            while ((read = reader.read(buff)) > 0) {
                response.append(buff, 0, read);
            }
            return response.toString();
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }

    /**
     * HTTPS GET请求
     *
     * @param url
     * @param headerMap
     * @return
     */
    public static String httpsGet(String url, Map<String, String> headerMap) {
        String str_return = "";
        HttpsURLConnection conn = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            if (headerMap != null) {
                Iterator<Map.Entry<String, String>> it = headerMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry<String, String> entry = it.next();
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.connect();
            InputStream is = conn.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(is, ("ISO-8859-1")));
            String ret = "";
            while (ret != null) {
                ret = br.readLine();
                if (ret != null && !ret.trim().equals("")) {
                    str_return = str_return + new String(ret.getBytes("ISO-8859-1"), "utf-8");
                }
            }
        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return str_return;
    }

}

// 定制Verifier
class TrustAnyHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
}

class TrustAnyTrustManager implements X509TrustManager {

    public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

    }

    public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }

}
