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

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
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.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpUtils {
   public static final int CONNECTION_TIMEOUT_MS = 25000;
   public static final int SO_TIMEOUT_MS = 25000;
   static final String CHARSET = "utf-8";
   static PoolingHttpClientConnectionManager connectionManager = null;

   public static String requestFor(Map<String, String> params, String apiType, String url) {
      HttpRequestBase request = null;
      try {
         if ("parseFile".equals(apiType)) {
            request = createPostRequest(params, url);
         } else {
            request = createGetRequest(params, url);
         }
         if (request == null)
            return null;
         DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
         HttpResponse response = sendRequest((HttpClient)defaultHttpClient, request);
         if (response == null)
            return null;
         return processResponse(response);
      } catch (Throwable e) {
         e.printStackTrace();
         return "Error";
      } finally {
         if (request != null)
            request.releaseConnection();
      }
   }

   public static HttpRequestBase createPostRequest(Map<String, String> params, String url) {
      List<NameValuePair> formParams = new ArrayList();

      for(Map.Entry<String, String> entry : params.entrySet()) {
         formParams.add(new BasicNameValuePair((String)entry.getKey(), ObjectUtils.getString(entry.getValue())));
      }

      HttpPost post = new HttpPost(url);

      try {
         StringEntity entity = new UrlEncodedFormEntity(formParams, "utf-8");
         post.setEntity(entity);
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      }

      return post;
   }

   public static HttpRequestBase createGetRequest(Map<String, String> params, String url) {
      HttpGet httpGet = null;

      try {
         URIBuilder builder = new URIBuilder(url);
         if (params != null) {
            for(String key : params.keySet()) {
               builder.addParameter(key, (String)params.get(key));
            }
         }

         URI uri = builder.build();
         httpGet = new HttpGet(uri);
      } catch (Exception e) {
         e.printStackTrace();
      }

      return httpGet;
   }

   public String get(CloseableHttpClient client, String url, Map<String, Object> vars, int connectTimeoutMillSec, int readTimeoutMillSec) throws Exception {
      String responseText = "";
      CloseableHttpResponse response = null;

      try {
         HttpGet httpGet = new HttpGet(url);
         httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
         if (vars.get("Referer") != null) {
            httpGet.addHeader("Referer", String.valueOf(vars.remove("Referer")));
         }

         if (connectTimeoutMillSec > 10000 && readTimeoutMillSec > 10000) {
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeoutMillSec).setConnectTimeout(readTimeoutMillSec).build();
            httpGet.setConfig(requestConfig);
         }

         response = client.execute(httpGet);
         HttpEntity entity = response.getEntity();
         String charset = "UTF-8";
         if (entity != null) {
            charset = getContentCharSet(entity);
            responseText = EntityUtils.toString(entity, charset);
         }
      } catch (Exception e) {
         throw new Exception(e);
      } finally {
         try {
            if (null != response) {
               response.close();
            }
         } catch (Exception e) {
            e.printStackTrace();
         }

      }

      vars.put("data", responseText);
      return responseText;
   }

   public static String getContentCharSet(final HttpEntity entity) throws ParseException {
      if (entity == null) {
         throw new IllegalArgumentException("HTTP entity may be null");
      } else {
         String charset = null;
         if (entity.getContentType() != null) {
            HeaderElement[] values = entity.getContentType().getElements();
            if (values.length > 0) {
               NameValuePair param = values[0].getParameterByName("charset");
               if (param != null) {
                  charset = param.getValue();
               }
            }
         }

         if ("".equals(charset) || null == charset) {
            charset = "UTF-8";
         }

         return charset;
      }
   }

   public static HttpClient getHttpClient() {
      if (connectionManager == null) {
         connectionManager = new PoolingHttpClientConnectionManager();
      }

      connectionManager.setMaxTotal(50);
      connectionManager.setDefaultMaxPerRoute(connectionManager.getMaxTotal());
      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
      httpClientBuilder.setConnectionManager(connectionManager);
      CloseableHttpClient httpClient = httpClientBuilder.build();
      return httpClient;
   }

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

   private static HttpResponse sendRequest(HttpClient httpClient, HttpRequestBase request) throws IOException {
      try {
         HttpResponse response = httpClient.execute(request);
         return response;
      } catch (IOException e) {
         throw e;
      }
   }

   public static String processResponse(HttpResponse response) throws IOException {
      HttpEntity entityRsp = response.getEntity();
      String httpResult = EntityUtils.toString(entityRsp, "utf-8");
      return response.getStatusLine().getStatusCode() == 200 ? httpResult : "Errer";
   }

   public static String doPostES(String url, String username, String password) {
      CloseableHttpClient httpClient = buildHttpClient();
      String result = null;

      try {
         String input = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));
         HttpGet httpPost = new HttpGet(url);
         httpPost.setHeader("content-type", "application/json;charset=UTF-8");
         new StringEntity("", "utf-8");
         httpPost.setHeader("Authorization", "Basic " + input);
         httpPost.setHeader("Connection", "keep-alive");
         HttpResponse response = httpClient.execute(httpPost);
         HttpEntity entity = response.getEntity();
         result = EntityUtils.toString(entity, "UTF-8");
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            httpClient.close();
         } catch (IOException e) {
            e.printStackTrace();
         }

      }

      return result;
   }

   public static CloseableHttpClient buildHttpClient() {
      CloseableHttpClient client = null;
      HttpClientBuilder build = HttpClientBuilder.create();
      client = build.build();
      return SkipHttpsUtil.wrapClient();
   }
}
