package com.shanghaichengdi.ghjgitem.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import sun.misc.BASE64Encoder;

/**
 * @Author: gll
 * @Description:
 * @Data: Create in 13:49 2020/9/30
 * @Modified By:
 */
@Slf4j
public class HttpClientUtils {

  private final static int DEFALUT_TIMEOUT = 10000;

  public static String doGetAndBase64(String url) {
    // 创建Httpclient对象
    CloseableHttpClient httpclient = HttpClients.createDefault();
    String resultString = "";
    CloseableHttpResponse response = null;
    try {
      // 创建uri
      URIBuilder builder = new URIBuilder(url);
      URI uri = builder.build();
      // 创建http GET请求
      HttpGet httpGet = new HttpGet(uri);
      RequestConfig requestConfig = RequestConfig.custom()
          .setConnectTimeout(10000).setSocketTimeout(10000).build();
      httpGet.setConfig(requestConfig);
      // 执行请求
      response = httpclient.execute(httpGet);
      // 判断返回状态是否为200
      if (response.getStatusLine().getStatusCode() == 200) {
        BASE64Encoder encoder = new BASE64Encoder();
        String var1 = encoder.encode(EntityUtils.toByteArray(response.getEntity()));
        resultString = var1;
      }
    } catch (Exception e) {
      e.printStackTrace();
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        if (httpclient != null) {
          httpclient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return resultString;
  }

  /**
   * 通过图片的url获取图片的base64字符串
   *
   * @param imgUrl 图片url
   * @return 返回图片base64的字符串
   */
  public static String image2Base64(String imgUrl) {
    URL url = null;
    InputStream is = null;
    ByteArrayOutputStream outStream = null;
    HttpURLConnection httpUrl = null;
    String resultString = "";
    try {
      url = new URL(imgUrl);
      httpUrl = (HttpURLConnection) url.openConnection();
      httpUrl.connect();
      httpUrl.getInputStream();
      is = httpUrl.getInputStream();
      outStream = new ByteArrayOutputStream();
      //创建一个Buffer字符串
      byte[] buffer = new byte[1024];
      //每次读取的字符串长度，如果为-1，代表全部读取完毕
      int len = 0;
      //使用一个输入流从buffer里把数据读取出来
      while ((len = is.read(buffer)) != -1) {
        //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
        outStream.write(buffer, 0, len);
      }
      // 对字节数组Base64编码
      BASE64Encoder base64Encoder = new BASE64Encoder();
      resultString = base64Encoder.encode(outStream.toByteArray());
    } catch (Exception e) {
      e.printStackTrace();
      resultString = e.getMessage();
    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (outStream != null) {
        try {
          outStream.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (httpUrl != null) {
        try {
          httpUrl.disconnect();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    return resultString;
  }

  public static String doGet(String url, Map<String, String> header, Map<String, String> param,
      Integer timeout) {
    // 创建Httpclient对象
    CloseableHttpClient httpclient = HttpClients.createDefault();
    String resultString = "";
    CloseableHttpResponse response = null;
    try {
      // 创建uri
      URIBuilder builder = new URIBuilder(url);
      if (param != null) {
        for (String key : param.keySet()) {
          builder.addParameter(key, param.get(key));
        }
      }
      URI uri = builder.build();
      // 创建http GET请求
      HttpGet httpGet = new HttpGet(uri);
      if (header != null) {
        for (String key : header.keySet()) {
          httpGet.addHeader(key, header.get(key));
        }
      }
      timeout = (timeout == null ? DEFALUT_TIMEOUT : timeout);
      RequestConfig requestConfig = RequestConfig.custom()
          .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
      httpGet.setConfig(requestConfig);
      // 执行请求
      response = httpclient.execute(httpGet);
      // 判断返回状态是否为200
      if (response.getStatusLine().getStatusCode() == 200) {
        resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
      }
    } catch (Exception e) {
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        if (httpclient != null) {
          httpclient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return resultString;
  }

  /**
   * @return java.lang.String
   * @Author 欧永卿
   * @Description //TODO 模拟post请求，传入url和headers请求头json参数
   * @Date 16:05 2021-06-30
   * @Param [url, headers, json]
   **/
  public static String Post(String url, Map<String, String> headers, String json) {
    String result = null;
    HttpURLConnection connection = null;
    OutputStream dos = null;
    InputStream ins = null;
    BufferedReader reader = null;
    try {
      URL get = new URL(url);
      connection = (HttpURLConnection) get.openConnection();
      connection.setDoOutput(true);
      connection.setDoInput(true);
      connection.setUseCaches(false);
      connection.setConnectTimeout(10000);
      connection.setReadTimeout(10000);
      connection.setRequestMethod("POST");
      Iterator var6 = headers.entrySet().iterator();

      while (var6.hasNext()) {
        Map.Entry<String, String> entry = (Map.Entry) var6.next();
        connection.setRequestProperty((String) entry.getKey(), (String) entry.getValue());
      }

      connection.setRequestProperty("Content-Type", "application/json");
      connection.connect();
      dos = connection.getOutputStream();
      dos.write(json.getBytes());
      dos.flush();
      dos.close();
      ins = connection.getInputStream();
      reader = new BufferedReader(new InputStreamReader(ins, "utf-8"));
      StringBuffer buffer = new StringBuffer();

      String line;
      while ((line = reader.readLine()) != null) {
        buffer.append(line);
        buffer.append("\r\n");
      }

      result = buffer.toString();
    } catch (Exception var11) {
      var11.printStackTrace();
      result = var11.getMessage();
    } finally {
      if (reader != null) {
        try {
          reader.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (dos != null) {
        try {
          dos.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (ins != null) {
        try {
          ins.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (connection != null) {
        try {
          connection.disconnect();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    return result;
  }


  /**
   * @return java.lang.String
   * @Author 欧永卿
   * @Description //TODO 模拟get请求，传入url和headers参数列表
   * @Date 16:04 2021-06-30
   * @Param [url, headers]
   **/
  public static String Get(String url, Map<String, String> headers) {
    String result = null;
    HttpURLConnection connection = null;
    InputStream ins = null;
    BufferedReader reader = null;
    try {
      URL get = new URL(url);
      connection = (HttpURLConnection) get
          .openConnection();
      //需要输出
      connection.setDoOutput(true);
      //需要输入
      connection.setDoInput(true);
      //不允许缓存
      connection.setUseCaches(false);
      connection.setConnectTimeout(10000);
      connection.setReadTimeout(10000);
      connection.setRequestMethod("GET");
      for (Map.Entry<String, String> entry : headers.entrySet()) {
        connection.setRequestProperty(entry.getKey(), entry.getValue());
      }

      connection.connect();
      ins = connection.getInputStream();

      reader = new BufferedReader(new InputStreamReader(ins, StandardCharsets.UTF_8));
      StringBuilder buffer = new StringBuilder();

      String line = null;
      while ((line = reader.readLine()) != null) {
        buffer.append(line);
        buffer.append("\r\n");
      }
      result = buffer.toString();

    } catch (Exception e) {
      e.printStackTrace();
      result = e.getMessage();
    } finally {
      if (reader != null) {
        try {
          reader.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (ins != null) {
        try {
          ins.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (connection != null) {
        try {
          connection.disconnect();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    return result;
  }

  public static String doGet(String url) {
    return doGet(url, null, null, null);
  }

  public static String doPost(String url, Map<String, String> param) {
    // 创建Httpclient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    String resultString = "";
    try {
      // 创建Http Post请求
      HttpPost httpPost = new HttpPost(url);
      // 创建参数列表
      if (param != null) {
        List<NameValuePair> paramList = new ArrayList<>();
        for (String key : param.keySet()) {
          paramList.add(new BasicNameValuePair(key, param.get(key)));
        }
        // 模拟表单
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "UTF-8");
        Integer timeout = DEFALUT_TIMEOUT;
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
        httpPost.setConfig(requestConfig);
        httpPost.setEntity(entity);
      }
      // 执行http请求
      response = httpClient.execute(httpPost);
      resultString = EntityUtils.toString(response.getEntity(), "utf-8");
    } catch (Exception e) {
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
        resultString = e.getMessage();
      }
    }

    return resultString;
  }

  public static String doPost(String url, Map<String, String> param, Integer timeout) {
    // 创建Httpclient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    String resultString = "";
    try {
      // 创建Http Post请求
      HttpPost httpPost = new HttpPost(url);
      // 创建参数列表
      if (param != null) {
        List<NameValuePair> paramList = new ArrayList<>();
        for (String key : param.keySet()) {
          paramList.add(new BasicNameValuePair(key, param.get(key)));
        }
        // 模拟表单
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "UTF-8");
        timeout = (timeout == null ? DEFALUT_TIMEOUT : timeout);
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
        httpPost.setConfig(requestConfig);
        httpPost.setEntity(entity);
      }
      // 执行http请求
      response = httpClient.execute(httpPost);
      resultString = EntityUtils.toString(response.getEntity(), "utf-8");
    } catch (Exception e) {
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return resultString;
  }

  public static String doPost(String url, String data) {
    String result = "";
    CloseableHttpResponse response = null;
    CloseableHttpClient httpClient = null;
    try {
      httpClient = HttpClients.createDefault();
      HttpPost httpPost = new HttpPost(url);
      httpPost.setEntity(new StringEntity(data, "utf-8"));
      response = httpClient.execute(httpPost);
      HttpEntity resEntity = response.getEntity();
      result = EntityUtils.toString(resEntity, "utf-8");
    } catch (Exception e) {
      result = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
      try {
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }

  public static String doPostJson(String url, String json, Integer timeout) {
    // 创建Httpclient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    String resultString = "";
    try {
      // 创建Http Post请求
      HttpPost httpPost = new HttpPost(url);
      timeout = (timeout == null ? DEFALUT_TIMEOUT : timeout);
      RequestConfig requestConfig = RequestConfig.custom()
          .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
      httpPost.setConfig(requestConfig);
      // 创建请求内容
      StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
      httpPost.setEntity(entity);

      if (url.indexOf("https") == 0) {
        //*********************这一段是为了绕过ssl验证****************
        //采用绕过验证的方式处理https请求
        SSLContext sslcontext = createIgnoreVerifySSL();

        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
            socketFactoryRegistry);
        HttpClients.custom().setConnectionManager(connManager);

        //创建自定义的httpclient对象
        httpClient = HttpClients.custom().setConnectionManager(connManager).build();
        //***********************************
      }
      // 执行http请求
      response = httpClient.execute(httpPost);
      resultString = EntityUtils.toString(response.getEntity(), "utf-8");
    } catch (Exception e) {
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
        resultString = e.getMessage();
      }
    }

    return resultString;
  }


  public static String doPostJson(String url, String json, Map<String, String> headMap,
      Integer timeout) {
    // 创建Httpclient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    String resultString = "";
    try {
      // 创建Http Post请求
      HttpPost httpPost = new HttpPost(url);
      timeout = (timeout == null ? DEFALUT_TIMEOUT : timeout);
      RequestConfig requestConfig = RequestConfig.custom()
          .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
      httpPost.setConfig(requestConfig);
      // 创建请求内容
      StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
      httpPost.setEntity(entity);
      for (Map.Entry<String, String> entry : headMap.entrySet()) {
        httpPost.addHeader(entry.getKey(), entry.getValue());
      }

      if (url.indexOf("https") == 0) {
        //*********************这一段是为了绕过ssl验证****************
        //采用绕过验证的方式处理https请求
        SSLContext sslcontext = createIgnoreVerifySSL();

        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
            socketFactoryRegistry);
        HttpClients.custom().setConnectionManager(connManager);

        //创建自定义的httpclient对象
        httpClient = HttpClients.custom().setConnectionManager(connManager).build();
        //***********************************
      }
      // 执行http请求
      response = httpClient.execute(httpPost);
      resultString = EntityUtils.toString(response.getEntity(), "utf-8");

    } catch (Exception e) {
      e.printStackTrace();
      resultString = e.getMessage();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
        resultString = e.getMessage();
      }
    }

    return resultString;
  }

  public static byte[] doPostJsonByte(String url, String json, Integer timeout) {
    // 创建Httpclient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    byte[] result = null;
    // 创建Http Post请求
    HttpPost httpPost = new HttpPost(url);
    timeout = (timeout == null ? DEFALUT_TIMEOUT : timeout);
    RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(timeout).setSocketTimeout(timeout).build();
    httpPost.setConfig(requestConfig);
    // 创建请求内容
    StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
    httpPost.setEntity(entity);
    // 执行http请求
    try {
      response = httpClient.execute(httpPost);
      result = EntityUtils.toByteArray(response.getEntity());
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (response != null) {
          response.close();
        }
        if (httpClient != null) {
          httpClient.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return result;
  }

  private static String replaceEnter(String str) {
    String reg = "[\n-\r]";
    Pattern p = Pattern.compile(reg);
    Matcher m = p.matcher(str);
    return m.replaceAll("");
  }

  /**
   * 绕过验证
   *
   * @return
   * @throws NoSuchAlgorithmException
   * @throws KeyManagementException
   */
  public static SSLContext createIgnoreVerifySSL()
      throws NoSuchAlgorithmException, KeyManagementException {
    SSLContext sc = SSLContext.getInstance("SSLv3");

    // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
    X509TrustManager trustManager = new X509TrustManager() {
      @Override
      public void checkClientTrusted(
          java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
          String paramString) throws CertificateException {
      }

      @Override
      public void checkServerTrusted(
          java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
          String paramString) throws CertificateException {
      }

      @Override
      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
      }
    };

    sc.init(null, new TrustManager[]{trustManager}, null);
    return sc;
  }
}
