package cn.superdesk.uniorder.common;

import cn.superdesk.uniorder.common.json.AnJsonUtils;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
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.client.protocol.HttpClientContext;
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.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


/**
 * @Description: 老方式 计划弃用
 * @Author: linjinyu
 * @CreateDate: 2021/10/27 下午2:42
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/10/27 下午2:42
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Deprecated
@Slf4j
public class HttpClientUtils {


	private static       PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;
	private static       RequestConfig                      requestConfig;
	private final static int                                defaultTimeout = 240000;
	private static       Charset                            encoding       = Consts.UTF_8;
	private static       SSLConnectionSocketFactory         socketFactory;
	private static       CloseableHttpClient                httpClient;

	static {
		requestConfig = RequestConfig.custom()
				.setSocketTimeout(defaultTimeout)
				.setConnectTimeout(defaultTimeout)
				.setConnectionRequestTimeout(defaultTimeout)
				.setCookieSpec(CookieSpecs.STANDARD_STRICT)
				.setRedirectsEnabled(false)
				.setExpectContinueEnabled(true)
				.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
				.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();

		if (poolingHttpClientConnectionManager == null) {

			IgnoreVerifySSL();

			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
					.register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", socketFactory).build();

			poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			// 整个连接池最大连接数
			// poolingHttpClientConnectionManager.setDefaultMaxPerRoute(5);
			// 每路由最大连接数,默认值是2
			poolingHttpClientConnectionManager.setMaxTotal(500);
		}

		DefaultHttpRequestRetryHandler dhr = new DefaultHttpRequestRetryHandler(3, true);
		httpClient = HttpClients
				.custom()
				.setConnectionManager(poolingHttpClientConnectionManager)
				.setRetryHandler(dhr)
				.build();

	}

	/**
	 * 忽略证书
	 */
	private static void IgnoreVerifySSL() {

		try {

			TrustManager manager = new X509TrustManager() {

				@Override
				public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
						throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
						throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			};
			// SSLv3
			SSLContext context = SSLContext.getInstance("TLS");
			context.init(null, new TrustManager[]{manager}, null);
			socketFactory = new SSLConnectionSocketFactory(context, NoopHostnameVerifier.INSTANCE);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 功能说明:POST方式提交参数
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午4:33:37
	 * @author liuli
	 */
	public static String doPost(String url) {
		return doPost(url, null);
	}

	public static String doPost(String url, String headerName, String headerValue) {

		return doPost(url, null, headerName, headerValue);
	}


	/**
	 * 功能说明:POST方式提交参数
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doPost(String url, Map<String, String> params) {

		log.info("\n########################## doPost start ################################\n" +
				"\nurl___ : " +
				"\nparams : " +
				"\n########################## doPost start ################################\n", url, AnJsonUtils.toJson(params));

		HttpPost httpPost = new HttpPost(url);

		List<NameValuePair> formparams = new ArrayList<NameValuePair>();

		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}

		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encoding);
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(entity);

		try {
			CloseableHttpResponse response   = httpClient.execute(httpPost, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				return resStr;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	public static String doPost(String url, Map<String, String> params, String headerName, String headerValue) {

		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader(headerName, headerValue);

		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}

		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encoding);

		httpPost.setConfig(requestConfig);
		httpPost.setEntity(entity);
		try {
			CloseableHttpResponse response   = httpClient.execute(httpPost, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				return resStr;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "";
	}

	/**
	 * 功能说明:POST方式提交参数
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doPost(String url, Map<String, String> params, Map<String, String> cookieMap) {

		HttpPost httpPost = new HttpPost(url);

		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}

		StringEntity entity = new StringEntity(JSONObject.toJSONString(params), encoding);
		entity.setContentType("text/json");
		httpPost.setEntity(entity);
		httpPost.setHeader("Accept", "application/json");
		httpPost.setHeader("Content-Type", "application/json");

		CookieStore cookieStore = new BasicCookieStore();

		if (cookieMap != null) {
			for (Entry<String, String> entry : cookieMap.entrySet()) {
				BasicClientCookie cookie = new BasicClientCookie(entry.getKey(), entry.getValue());
				cookie.setDomain(getDomain(url));
				cookie.setPath("/");
				cookie.setSecure(false);
				cookieStore.addCookie(cookie);
				httpPost.setHeader("cookie", entry.toString());
			}

		}

		try {
			CloseableHttpResponse response   = httpClient.execute(httpPost);
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				return resStr;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 功能说明:POST方式提交参数并获取Header指定参数Name值
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doPostResultFirstHeader(String url, String headerName) {
		return doPostResultFirstHeader(url, null, headerName);
	}

	/**
	 * 功能说明:POST方式提交参数并获取Header指定参数Name值
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doPostResultFirstHeader(String url, Map<String, String> params, String headerName) {

		HttpPost httpPost = new HttpPost(url);

		List<NameValuePair> formparams = new ArrayList<NameValuePair>();

		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}

		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encoding);
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(entity);

		try {
			CloseableHttpResponse response   = httpClient.execute(httpPost, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				Header header = response.getFirstHeader(headerName);
				return header.getValue();
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明:POST方式提交参数并获取Header信息
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static Header[] doPostResultHeader(String url) {
		return doPostResultHeader(url, null);
	}

	/**
	 * 功能说明:POST方式提交参数并获取Header信息
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static Header[] doPostResultHeader(String url, Map<String, String> params) {

		HttpPost httpPost = new HttpPost(url);

		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		if (params != null) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
			}
		}
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encoding);
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(entity);

		try {

			CloseableHttpResponse response = httpClient.execute(httpPost, HttpClientContext.create());

			HttpEntity httpEntity = response.getEntity();
			if (httpEntity != null) {
				Header[] headers = response.getAllHeaders();
				return headers;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明:POST方式提交请求
	 *
	 * @param url     请求URL
	 * @param jsonStr 请求参数json格式
	 * @return
	 * @createTime 2018年4月10日 下午3:37:19
	 * @author liuli
	 */
	public static String doPostJson(String url, String jsonStr) {

		HttpPost httpPost = new HttpPost(url);

		StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON);

		httpPost.setConfig(requestConfig);

		httpPost.setEntity(entity);
		try {
			CloseableHttpResponse response   = httpClient.execute(httpPost, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				return resStr;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 功能说明:GET方式提交请求
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午3:38:41
	 * @author liuli
	 */
	public static String doGet(String url) {
		return doGet(url, null);
	}

	/**
	 * 功能说明:GET方式提交请求
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:38:41
	 * @author liuli
	 */
	public static String doGet(String url, Map<String, String> params) {
		String parameters = "";
		if (params != null) {
			StringBuffer stringBuffer = new StringBuffer();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			if (stringBuffer.length() > 0) {
				parameters = stringBuffer.substring(0, stringBuffer.length() - 1);
			}
			url = url + "?" + parameters;
		}
		HttpGet httpGet = new HttpGet(url);
		httpGet.setConfig(requestConfig);
		httpGet.addHeader(new BasicHeader("Content-Type", "multipart/form-data;charset=utf-8"));
		try {
			CloseableHttpResponse response   = httpClient.execute(httpGet, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				return resStr;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 功能说明:GET方式提交请求并获取Header信息
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午4:38:04
	 * @author liuli
	 */
	public static Header[] doGetResultHeader(String url) {
		return doGetResultHeader(url, null);
	}

	/**
	 * 功能说明:GET方式提交请求并获取Header信息
	 *
	 * @param url    请求URL
	 * @param params 请求参数
	 * @return
	 * @createTime 2018年4月10日 下午3:38:41
	 * @author liuli
	 */
	public static Header[] doGetResultHeader(String url, Map<String, String> params) {
		String parameters = "";
		if (params != null) {
			StringBuffer stringBuffer = new StringBuffer();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			if (stringBuffer.length() > 0) {
				parameters = stringBuffer.substring(0, stringBuffer.length() - 1);
			}
			url = url + "?" + parameters;
		}
		HttpGet httpGet = new HttpGet(url);
		httpGet.setConfig(requestConfig);
		httpGet.addHeader(new BasicHeader("Content-Type", "multipart/form-data;charset=utf-8"));
		try {
			CloseableHttpResponse response   = httpClient.execute(httpGet, HttpClientContext.create());
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				return response.getAllHeaders();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明:GET方式提交参数并获取Header指定参数Name值
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doGetResultFirstHeader(String url, String headerName) {
		return doGetResultFirstHeader(url, null, headerName);
	}

	/**
	 * 功能说明:GET方式提交参数并获取Header指定参数Name值
	 *
	 * @param url 请求URL
	 * @return
	 * @createTime 2018年4月10日 下午3:36:43
	 * @author liuli
	 */
	public static String doGetResultFirstHeader(String url, Map<String, String> params, String headerName) {
		String parameters = "";
		if (params != null) {
			StringBuffer stringBuffer = new StringBuffer();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			if (stringBuffer.length() > 0) {
				parameters = stringBuffer.substring(0, stringBuffer.length() - 1);
			}
			url = url + "?" + parameters;
		}
		HttpGet httpGet = new HttpGet(url);
		httpGet.addHeader(new BasicHeader("Content-Type", "multipart/form-data;charset=utf-8"));
		try {
			CloseableHttpResponse response   = httpClient.execute(httpGet);
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				Header header = response.getFirstHeader(headerName);
				return header.getValue();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能说明:读取流
	 *
	 * @param is      输入流
	 * @param charset 编码格式
	 * @return
	 * @createTime 2018年4月10日 下午3:39:10
	 * @author liuli
	 */
	public static String readInputStream(InputStream is, Charset charset) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		byte[]                buffer       = new byte[1024];
		int                   len          = 0;
		String                result       = "";
		if (is != null) {
			try {
				while ((len = is.read(buffer)) != -1) {
					outputStream.write(buffer, 0, len);
				}
				result = new String(outputStream.toByteArray(), charset);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public static String getDomain(String url) {
		String host = null;

		try {
			URI uri = new URI(url);
			host = uri.getHost();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return host;
	}

	/**
	 * 功能说明:
	 *
	 * @param httpUrl
	 * @param maps
	 * @param cookie
	 * @param multipartFiles
	 * @return
	 * @createTime 2018年7月10日 下午5:26:00
	 * @author liuli
	 */
	public static String doPostFiles(String httpUrl, Map<String, String> maps, String cookie,
	                                 List<MultipartFile> multipartFiles) {
		HttpPost               httpPost  = new HttpPost(httpUrl);// 创建httpPost
		MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
		if (maps != null && maps.size() > 0) {
			for (String key : maps.keySet()) {
				meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
			}
		}
		DefaultHttpRequestRetryHandler dhr         = new DefaultHttpRequestRetryHandler(3, true);
		CloseableHttpClient            httpClient1 = HttpClients.custom().setRetryHandler(dhr).build();
		try {
			int index = 0;
			for (MultipartFile inputStream : multipartFiles) {
				InputStream     stream          = inputStream.getInputStream();
				InputStreamBody inputStreamBody = new InputStreamBody(stream, inputStream.getOriginalFilename());
				meBuilder.addPart("files[" + index + "]", inputStreamBody);
				index++;
			}
			HttpEntity reqEntity = meBuilder.build();
			httpPost.setEntity(reqEntity);
			httpPost.addHeader("Cookie", cookie);
			CloseableHttpResponse response   = httpClient1.execute(httpPost);
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				httpClient1.close();
				response.close();
				return resStr;
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 功能说明:
	 *
	 * @param httpUrl
	 * @param maps
	 * @param cookie
	 * @return
	 * @createTime 2018年7月10日 下午5:03:07
	 * @author liuli
	 */
	public static String sendHttpPost(String httpUrl, Map<String, String> maps, String cookie) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		try {
			httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
			Gson         gson      = new Gson();
			String       parameter = gson.toJson(maps);
			StringEntity se        = new StringEntity(parameter);
			se.setContentType("text/json");
			httpPost.setEntity(se);
			httpPost.addHeader("Cookie", cookie);
			CloseableHttpResponse response   = httpClient.execute(httpPost);
			HttpEntity            httpEntity = response.getEntity();
			if (httpEntity != null) {
				String resStr = EntityUtils.toString(httpEntity, "UTF-8");
				log.info("返回结果:", resStr);
				return resStr;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
}
