package com.mosty.hczx.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
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.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.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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 javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.*;

@Slf4j
public class HttpClientUtils {


	public static final String CHARSET = "UTF-8";
	private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000).setConnectionRequestTimeout(15000).build();

		public static String doGet(String url, Map<String, String> params) {
		return doGet(url, params, CHARSET);
	}
	
	public static String doGetSSL(String url, Map<String, String> params) {
		return doGetSSL(url, params, CHARSET);
	}

	public static String doPost(String url, Map<String, String> params) {
		return doPost(url, params, CHARSET);
	}

	public static String doPostForJson(String url, String json) {
		return doPostForJson(url, json, CHARSET);
	}
	
	public static String doPostForJson(String url, String json, Map<String, String> headersMap) {
		return doPostForJsonHeaders(url, json, CHARSET, headersMap);
	}
	
	public static String doPostSSLForJson(String url, String json) {
		return doPostSSLForJson(url, json, CHARSET);
	}

	/**
	 * HTTP GET
	 * 
	 * @param url
	 *            请求的url地址 ?之前的地址
	 * @param params
	 *            请求的参数
	 * @param charset
	 *            编码格式
	 * @return 页面内容
	 */
	public static String doGet(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				// 将请求参数和url进行拼接
				url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
			}
			HttpGet httpGet = new HttpGet(url);
			httpGet.setConfig(REQUEST_CONFIG);

			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			response = httpClient.execute(httpGet);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpGet.abort();
				return "HttpClient, error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}
	
	/**
	 * @Title: doGetSSL
	 * @Description: get https
	 * @param url
	 * @param params
	 * @param charset
	 * @return String
	 */
	public static String doGetSSL(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				// 将请求参数和url进行拼接
				url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
			}
			HttpGet httpGet = new HttpGet(url);
			httpGet.setConfig(REQUEST_CONFIG);

			// 创建默认的httpClient实例. 在调用SSL之前需要重写验证方法，取消检测SSL
			X509TrustManager trustManager = new X509TrustManager() {
				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}

				@Override
				public void checkClientTrusted(X509Certificate[] xcs, String str) {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] xcs, String str) {
				}
			};
			SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
			ctx.init(null, new TrustManager[] { trustManager }, null);
			SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
			RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(Boolean.TRUE)
					.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", socketFactory).build();
			// 创建ConnectionManager，添加Connection配置信息
			PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();

			httpGet.addHeader("AppKey", "679049566846189568");
			
			response = httpClient.execute(httpGet);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpGet.abort();
				return "HttpClient, error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}

	/**
	 * HTTP POST
	 * 
	 * @param url
	 *            请求的url地址 ?之前的地址
	 * @param params
	 *            请求的参数
	 * @param charset
	 *            编码格式
	 * @return 页面内容
	 */
	public static String doPost(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		//log.info("doPost url: " + url);
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			List<NameValuePair> pairs = null;
			if (params != null && !params.isEmpty()) {
				pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				//log.info("doPost pairs: " + JacksonUtils.objToJson(pairs));
			}
			HttpPost httpPost = new HttpPost(url);
			if (pairs != null && pairs.size() > 0) {
				httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
			}
			httpPost.setConfig(REQUEST_CONFIG);
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			response = httpClient.execute(httpPost);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				httpPost.abort();
				return "HttpClient,	error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			log.info("doPost HttpEntity: " + result);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}

	/**
	 * HTTP POST 参数为json
	 * 
	 * @param url
	 * @param json
	 * @param charset
	 * @return
	 */
	public static String doPostForJson(String url, String json, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
//		log.info("doPostForJson url: " + url);
//		log.info("doPostForJson json: " + json);
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			
			StringEntity stringentity = new StringEntity(json, charset);
			stringentity.setContentType("application/json");

			httpPost.setEntity(stringentity);
			httpPost.setConfig(REQUEST_CONFIG);
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			// 执行请求
			response = httpClient.execute(httpPost);

			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				httpPost.abort();
				return "HttpClient,	error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
//			log.info("doPostForJson HttpEntity: " + result);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}

	/**
	 * HTTP POST 参数为json
	 * 
	 * @param url
	 * @param json
	 * @param charset
	 * @return
	 */
	public static String doPostForJsonHeaders(String url, String json, String charset, Map<String, String> headersMap) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		log.info("doPostForJson url: " + url);
		//log.info("doPostForJson json: " + json);
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			
			StringEntity stringentity = new StringEntity(json, charset);
			stringentity.setContentType("application/json");

			//请求头部
			if(null != headersMap && !headersMap.isEmpty()){
				Iterator<Map.Entry<String, String>> itr = headersMap.entrySet().iterator();
				while(itr.hasNext()){
					Map.Entry<String, String> ent = itr.next();
					httpPost.addHeader(ent.getKey(), ent.getValue());
				}
			}
			
			httpPost.setEntity(stringentity);
			httpPost.setConfig(REQUEST_CONFIG);
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			// 执行请求
			response = httpClient.execute(httpPost);

			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				httpPost.abort();
				return "HttpClient,	error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			log.info("doPostForJson HttpEntity: " + result);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}
	
	/**
	 * @Title: doPostSSLForJson
	 * @Description: post https
	 * @param url
	 * @param json
	 * @param charset
	 * @return String
	 */
	public static String doPostSSLForJson(String url, String json, String charset) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			HttpPost httpPost = new HttpPost(url);

			StringEntity stringentity = new StringEntity(json, charset);
			stringentity.setContentType("application/json");

			httpPost.setEntity(stringentity);
			httpPost.setConfig(REQUEST_CONFIG);

			// 在调用SSL之前需要重写验证方法，取消检测SSL
			X509TrustManager trustManager = new X509TrustManager() {
				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
				@Override
				public void checkClientTrusted(X509Certificate[] xcs, String str) {
				}
				@Override
				public void checkServerTrusted(X509Certificate[] xcs, String str) {
				}
			};
			SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
			ctx.init(null, new TrustManager[] { trustManager }, null);
			SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
			RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(Boolean.TRUE)
					.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
					.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", socketFactory).build();
			// 创建ConnectionManager，添加Connection配置信息
			PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();

			// 执行请求
			response = httpClient.execute(httpPost);

			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				httpPost.abort();
				return "HttpClient,	error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}
	
	/**
	 * doGetForJson（json方式的get请求）
	 * @param url
	 * @param params
	 * @param charset
	 * @return
	 */
	public static String doGetForJson(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				// 将请求参数和url进行拼接
				url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
			}
			HttpGet httpGet = new HttpGet(url);
			httpGet.setConfig(REQUEST_CONFIG);
			httpGet.setHeader("Content-Type", "application/json;charset=UTF-8");

			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			response = httpClient.execute(httpGet);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpGet.abort();
				return "HttpClient, error status code : " + statusCode;
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			return result;
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return null;
	}

	public static void main(String[] args) {
		System.out.println("2".contains("1,2"));
	}
	
}
