package com.persagy.framework.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.apache.http.client.config.RequestConfig;
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.HttpUriRequest;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.InputStreamEntity;
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.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;
import com.persagy.core.constant.SystemConstant;

/**
 * Http请求工具类
 */
public class HttpUtil {
	private final static PoolingHttpClientConnectionManager CONNECTION_MANAGER = new PoolingHttpClientConnectionManager();
	private final static CloseableHttpClient HTTP_CLIENT;
	private static final String UTF8 = "utf-8";

	static {
		// 设置整个连接池最大连接数 根据自己的场景决定
		CONNECTION_MANAGER.setMaxTotal(200);
		// 每个路由(网站)的最大连接数
		CONNECTION_MANAGER.setDefaultMaxPerRoute(100);
		RequestConfig requestConfig = RequestConfig.custom()
				// 连接建立时间，三次握手完成时间
				.setConnectTimeout(5000)
				// 数据传输过程中数据包之间间隔的最大时间
				.setSocketTimeout(8000)
				// httpClient使用连接池来管理连接，这个时间就是从连接池获取连接的超时时间
				.setConnectionRequestTimeout(6000).build();
		HTTP_CLIENT = HttpClients.custom().setConnectionManager(CONNECTION_MANAGER)
				.setDefaultRequestConfig(requestConfig).build();
	}

	/**
	 * get请求
	 * @param url
	 * @return 结果字符串
	 * @throws Exception
	 */
	public static String get(String url) throws Exception {
		HttpGet httpGet = new HttpGet(url);
		return sendRequest(httpGet);
	}

	/**
	 * post请求
	 * @param url
	 * @return 结果字符串
	 * @throws Exception
	 */
	public static String post(String url) throws Exception {
		HttpPost httpPost = new HttpPost(url);
		return sendRequest(httpPost);
	}

	/**
	 * post请求
	 * @param url
	 * @param params 请求参数
	 * @return
	 * @throws IOException
	 */
	public static String post(String url, Map<String, String> params) throws IOException {
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		httpPost.setEntity(new StringEntity(SystemConstant.jsonMapper.writeValueAsString(params), UTF8));
		String respContent = sendRequest(httpPost);
		return respContent;
	}
	
	/**
	 * post请求
	 * @param url
	 * @param params 请求参数
	 * @return
	 * @throws IOException
	 */
	public static String post(String url, JSONObject params) throws IOException {
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		httpPost.setEntity(new StringEntity(SystemConstant.jsonMapper.writeValueAsString(params), UTF8));
		String respContent = sendRequest(httpPost);
		return respContent;
	}
	
	private static String sendRequest(HttpUriRequest request) throws IOException {
		CloseableHttpResponse response = HTTP_CLIENT.execute(request);
		return EntityUtils.toString(response.getEntity(), UTF8);
	}

	/**
	 * post请求
	 * @param url
	 * @param is 输入数据流，body体数据
	 * @return
	 * @throws Exception
	 */
	public static String post(String url, InputStream is) throws Exception {
		HttpPost httpPost = new HttpPost(url);
		httpPost.setEntity(new InputStreamEntity(is));
		return sendRequest(httpPost);
	}

	/**
	 * post请求
	 * @param url
	 * @param file 文件实例
	 * @return
	 * @throws Exception
	 */
	public static String post(String url, File file) throws Exception {
		HttpPost httpPost = new HttpPost(url);
		httpPost.setEntity(new FileEntity(file));
		return sendRequest(httpPost);
	}

	/**
	 * get请求
	 * @param url
	 * @return 字节数组
	 * @throws Exception
	 */
	public static byte[] getData(String url) throws Exception {
		HttpGet httpGet = new HttpGet(url);
		CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet);
		return EntityUtils.toByteArray(response.getEntity());
	}

}
