package com.chenyang.nse.bussiness.tools.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
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.HttpClientBuilder;
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 org.springframework.util.Assert;

public class HttpClientUtils {
   public static final int CONNECTION_TIMEOUT_MS = 25000;
   public static final int SO_TIMEOUT_MS = 25000;
   public static final String CHARSET = "UTF-8";
   private static PoolingHttpClientConnectionManager httpConnMgr = new PoolingHttpClientConnectionManager();
   private static PoolingHttpClientConnectionManager httpsConnMgr;

   private HttpClientUtils() {
   }

   public static HttpClient buildHttpClient(boolean isMultiThread) {
      CloseableHttpClient client;
      if (isMultiThread) {
         client = HttpClientBuilder.create().setConnectionManager(httpConnMgr).build();
      } else {
         client = HttpClientBuilder.create().build();
      }

      return client;
   }

   public static HttpClient buildHttpsClient(boolean isMultiThread) {
      CloseableHttpClient client;
      if (isMultiThread) {
         client = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(httpsConnMgr).build();
      } else {
         client = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).build();
      }

      return client;
   }

   private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
      SSLConnectionSocketFactory sslsf = null;
      X509TrustManager x509mgr = new X509TrustManager() {
         public void checkClientTrusted(X509Certificate[] xcs, String string) {
         }

         public void checkServerTrusted(X509Certificate[] xcs, String string) {
         }

         public X509Certificate[] getAcceptedIssuers() {
            return null;
         }
      };
      SSLContext sslContext = null;

      try {
         sslContext = SSLContext.getInstance("TLS");
         sslContext.init((KeyManager[])null, new TrustManager[]{x509mgr}, new SecureRandom());
      } catch (NoSuchAlgorithmException | KeyManagementException e) {
         ((GeneralSecurityException)e).printStackTrace();
      }

      HostnameVerifier hv = new HostnameVerifier() {
         public boolean verify(String hostname, SSLSession session) {
            return true;
         }
      };
      sslsf = new SSLConnectionSocketFactory(sslContext, hv);
      return sslsf;
   }

   public static void setContentLength(HttpRequestBase httpMethod, HttpEntity he) {
      if (he != null) {
         httpMethod.setHeader("Content-Length", String.valueOf(he.getContentLength()));
      }
   }

   public static RequestConfig buildRequestConfig() {
      RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(25000).setConnectTimeout(25000).build();
      return requestConfig;
   }

   public static HttpGet buildHttpGet(String url, Map<String, Object> params) throws URISyntaxException {
      Assert.notNull(url, "构建HttpGet时,url不能为null");
      HttpGet get = new HttpGet(buildGetUrl(url, params));
      setCommonHttpMethod(get);
      get.setConfig(buildRequestConfig());
      return get;
   }

   public static HttpPost buildHttpPost(String url, Map<String, Object> params, String charset) throws UnsupportedEncodingException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPost post = new HttpPost(url);
      setCommonHttpMethod(post);
      post.setConfig(buildRequestConfig());
      HttpEntity he = null;
      if (params != null) {
         List<NameValuePair> formparams = new ArrayList();

         for(String key : params.keySet()) {
            formparams.add(new BasicNameValuePair(key, params.get(key) + ""));
         }

         HttpEntity var8 = new UrlEncodedFormEntity(formparams, charset);
         post.setEntity(var8);
      }

      return post;
   }

   public static HttpPost buildHttpPost(String url, String params, String charset) throws UnsupportedEncodingException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPost post = new HttpPost(url);
      setCommonHttpMethod(post);
      post.setConfig(buildRequestConfig());
      StringEntity entity = new StringEntity(params, charset);
      post.setEntity(entity);
      return post;
   }

   public static HttpPost buildHttpPost(String url, String params) throws UnsupportedEncodingException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      return buildHttpPost(url, params, "UTF-8");
   }

   public static void setCommonHttpMethod(HttpRequestBase httpMethod) {
   }

   public static void setCommonHttpMethod(HttpRequestBase httpMethod, Map<String, String> contentTypeMap) {
      if (null != contentTypeMap && contentTypeMap.size() > 0) {
         for(String contentType : contentTypeMap.keySet()) {
            httpMethod.setHeader(contentType, (String)contentTypeMap.get(contentType));
         }
      } else {
         setCommonHttpMethod(httpMethod);
      }

   }

   static void assertStatus(HttpResponse res) throws IOException {
      Assert.notNull(res, "http响应对象为null");
      Assert.notNull(res.getStatusLine(), "http响应对象的状态为null");
      switch (res.getStatusLine().getStatusCode()) {
         case 200:
            return;
         default:
            throw new IOException("服务器响应状态异常,失败.");
      }
   }

   public static String processResponse(HttpResponse response) throws ClientProtocolException, IOException, URISyntaxException {
      return processResponse(response, "UTF-8");
   }

   public static String processResponse(HttpResponse response, String charset) throws ClientProtocolException, IOException, URISyntaxException {
      HttpEntity entity = response.getEntity();
      if (entity != null) {
         String returnStr = EntityUtils.toString(entity, charset);
         return returnStr;
      } else {
         return null;
      }
   }

   public static String doGet(String url) throws ClientProtocolException, IOException, URISyntaxException {
      return doGet(url, (Map)null);
   }

   public static String doGet(String url, Map<String, Object> params) throws ClientProtocolException, IOException, URISyntaxException {
      return doGet(url, params, "UTF-8");
   }

   public static String doGet(String url, Map<String, Object> params, String charset) throws ClientProtocolException, IOException, URISyntaxException {
      HttpClient client = buildHttpClient(false);
      HttpGet get = buildHttpGet(url, params);
      HttpResponse response = client.execute(get);
      return processResponse(response, charset);
   }

   public static byte[] doGetBuffer(String url) throws ClientProtocolException, IOException, URISyntaxException {
      HttpClient client = buildHttpClient(false);
      HttpGet get = buildHttpGet(url, (Map)null);
      HttpResponse response = client.execute(get);
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode != 200) {
         return null;
      } else {
         HttpEntity entity = response.getEntity();
         if (entity != null) {
            InputStream stream = entity.getContent();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            Throwable var8 = null;

            byte[] var10;
            try {
               int read = -1;

               while((read = stream.read()) != -1) {
                  output.write(read);
                  output.flush();
               }

               var10 = output.toByteArray();
            } catch (Throwable var19) {
               var8 = var19;
               throw var19;
            } finally {
               if (output != null) {
                  if (var8 != null) {
                     try {
                        output.close();
                     } catch (Throwable var18) {
                        var8.addSuppressed(var18);
                     }
                  } else {
                     output.close();
                  }
               }

            }

            return var10;
         } else {
            return null;
         }
      }
   }

   public static String doGetSSL(String url) throws ClientProtocolException, IOException, URISyntaxException {
      return doGetSSL(url, (Map)null);
   }

   public static String doGetSSL(String url, Map<String, Object> params) throws ClientProtocolException, IOException, URISyntaxException {
      return doGetSSL(url, params, "UTF-8");
   }

   public static String doGetSSL(String url, Map<String, Object> params, String charset) throws ClientProtocolException, IOException, URISyntaxException {
      HttpClient client = buildHttpsClient(false);
      HttpGet get = buildHttpGet(url, params);
      HttpResponse response = client.execute(get);
      return processResponse(response, charset);
   }

   public static String doPost(String url, Map<String, Object> params) throws URISyntaxException, ClientProtocolException, IOException {
      return doPost(url, params, "UTF-8");
   }

   public static String doPost(String url, Map<String, Object> params, String charset) throws URISyntaxException, ClientProtocolException, IOException {
      HttpClient client = buildHttpClient(false);
      HttpPost postMethod = buildHttpPost(url, params, charset);
      HttpResponse response = client.execute(postMethod);
      return processResponse(response, charset);
   }

   public static String doPost(String url, String params) throws URISyntaxException, ClientProtocolException, IOException {
      return doPost(url, params, "UTF-8");
   }

   public static String doPost(String url, String params, String charset) throws URISyntaxException, ClientProtocolException, IOException {
      HttpClient client = buildHttpClient(false);
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPost postMethod = buildHttpPost(url, params, charset);
      postMethod.setConfig(buildRequestConfig());
      HttpResponse response = client.execute(postMethod);
      return processResponse(response, charset);
   }

   public static String doPostSSL(String url, Map<String, Object> params) throws URISyntaxException, ClientProtocolException, IOException {
      return doPostSSL(url, params, "UTF-8");
   }

   public static String doPostSSL(String url, Map<String, Object> params, String charset) throws URISyntaxException, ClientProtocolException, IOException {
      HttpClient client = buildHttpsClient(false);
      HttpPost postMethod = buildHttpPost(url, params, charset);
      HttpResponse response = client.execute(postMethod);
      return processResponse(response, charset);
   }

   public static String doPostSSL(String url, String params) throws URISyntaxException, ClientProtocolException, IOException {
      return doPostSSL(url, params, "UTF-8");
   }

   public static String doPostSSL(String url, String params, String charset) throws URISyntaxException, ClientProtocolException, IOException {
      HttpClient client = buildHttpsClient(false);
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPost postMethod = buildHttpPost(url, params, charset);
      postMethod.setConfig(buildRequestConfig());
      HttpResponse response = client.execute(postMethod);
      return processResponse(response, charset);
   }

   private static String buildGetUrl(String url, Map<String, Object> params) {
      StringBuffer uriStr = new StringBuffer(url);
      if (params != null) {
         List<NameValuePair> ps = new ArrayList();

         for(String key : params.keySet()) {
            ps.add(new BasicNameValuePair(key, params.get(key) + ""));
         }

         uriStr.append("?");
         uriStr.append(URLEncodedUtils.format(ps, "UTF-8"));
      }

      return uriStr.toString();
   }

   public static String doPut(String url) throws Exception {
      return doPut(url, (Map)null);
   }

   public static String doPut(String url, Map<String, Object> params) throws Exception {
      return doPut(url, params, "UTF-8");
   }

   public static String doPut(String url, Map<String, Object> params, String charset) throws Exception {
      HttpClient client = buildHttpClient(false);
      HttpPut putMethod = buildHttpPut(url, params, charset);
      HttpResponse response = client.execute(putMethod);
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
         return processResponseError(response, "UTF-8");
      } else if (statusCode == 307) {
         Header location = response.getFirstHeader("Location");
         if (location == null) {
            throw new Exception("重定向的URL为空");
         } else {
            String newUrl = location.getValue();
            return doPut(newUrl, params, charset);
         }
      } else {
         return processResponseError(response, "UTF-8");
      }
   }

   static String processResponseError(HttpResponse response, String charset) {
      if (response == null) {
         return "";
      } else {
         HttpEntity entity = response.getEntity();
         if (entity == null) {
            return "";
         } else {
            try {
               InputStream stream = entity.getContent();
               Throwable var4 = null;

               String var8;
               try {
                  ByteArrayOutputStream output = new ByteArrayOutputStream();
                  Throwable var6 = null;

                  try {
                     int read = -1;

                     while((read = stream.read()) != -1) {
                        output.write(read);
                        output.flush();
                     }

                     var8 = new String(output.toByteArray(), charset);
                  } catch (Throwable var33) {
                     var6 = var33;
                     throw var33;
                  } finally {
                     if (output != null) {
                        if (var6 != null) {
                           try {
                              output.close();
                           } catch (Throwable var32) {
                              var6.addSuppressed(var32);
                           }
                        } else {
                           output.close();
                        }
                     }

                  }
               } catch (Throwable var35) {
                  var4 = var35;
                  throw var35;
               } finally {
                  if (stream != null) {
                     if (var4 != null) {
                        try {
                           stream.close();
                        } catch (Throwable var31) {
                           var4.addSuppressed(var31);
                        }
                     } else {
                        stream.close();
                     }
                  }

               }

               return var8;
            } catch (Exception var37) {
               return "";
            }
         }
      }
   }

   public static HttpPut buildHttpPut(String url, Map<String, Object> params, String charset) throws UnsupportedEncodingException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPut put = new HttpPut(url);
      setCommonHttpMethod(put);
      put.setConfig(buildRequestConfig());
      HttpEntity he = null;
      if (params != null) {
         List<NameValuePair> formparams = new ArrayList();

         for(String key : params.keySet()) {
            formparams.add(new BasicNameValuePair(key, params.get(key) + ""));
         }

         HttpEntity var8 = new UrlEncodedFormEntity(formparams, charset);
         put.setEntity(var8);
      }

      return put;
   }

   public static String doPut(String url, byte[] content) throws ClientProtocolException, IOException, URISyntaxException {
      return doPut(url, content, "UTF-8");
   }

   public static String doPut(String url, byte[] content, String charset) throws URISyntaxException, ClientProtocolException, IOException {
      HttpClient client = buildHttpClient(false);
      HttpPut putMethod = buildHttpPut(url, content);
      HttpResponse response = client.execute(putMethod);
      return processResponse(response, charset);
   }

   public static HttpPut buildHttpPut(String url, byte[] content) throws UnsupportedEncodingException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPut put = new HttpPut(url);
      setCommonHttpMethod(put);
      put.setConfig(buildRequestConfig());
      ByteArrayEntity entity = new ByteArrayEntity(content);
      put.setEntity(entity);
      return put;
   }

   public static String doPost(String url, byte[] content) throws Exception {
      HttpClient client = buildHttpClient(false);
      HttpPost putMethod = buildHttpPost(url, content);
      HttpResponse response = client.execute(putMethod);
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode == 200) {
         return processResponseError(response, "UTF-8");
      } else if (statusCode == 307) {
         Header location = response.getFirstHeader("Location");
         if (location == null) {
            throw new Exception("上传文件失败，重定向的URL为空");
         } else {
            String newUrl = location.getValue();
            return doPost(newUrl, content);
         }
      } else {
         return processResponseError(response, "UTF-8");
      }
   }

   public static HttpPost buildHttpPost(String url, byte[] content) throws IOException, URISyntaxException {
      Assert.notNull(url, "构建HttpPost时,url不能为null");
      HttpPost post = new HttpPost(url);
      setCommonHttpMethod(post);
      MultipartEntityBuilder builder = MultipartEntityBuilder.create();
      ByteArrayEntity arrayEntity = new ByteArrayEntity(content);
      builder.addBinaryBody("data", content);
      HttpEntity entity = builder.build();
      post.setEntity(arrayEntity);
      return post;
   }

   public static String doDelete(String url) throws ClientProtocolException, IOException, URISyntaxException {
      HttpClient client = buildHttpClient(false);
      HttpDelete delete = new HttpDelete(url);
      setCommonHttpMethod(delete);
      delete.setConfig(buildRequestConfig());
      HttpResponse response = client.execute(delete);
      return processResponse(response, "UTF-8");
   }

   static {
      httpConnMgr.setMaxTotal(50);
      httpConnMgr.setDefaultMaxPerRoute(httpConnMgr.getMaxTotal());
      httpsConnMgr = new PoolingHttpClientConnectionManager();
      httpsConnMgr.setMaxTotal(50);
      httpsConnMgr.setDefaultMaxPerRoute(httpsConnMgr.getMaxTotal());
   }
}
