package com.jpsoft.shinestar.modules.common.utils;

import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
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.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

public class HttpConnectionUtil {
	private static int connectTimeoutMs = 10000;
	private static int readTimeoutMs = 10000;
	private static String charSet = "UTF-8";

	public static String getHttpContent(String url) {
        return getHttpContent(url, "UTF-8");
    }

    public static String getHttpContent(String url, String charSet) {
        HttpURLConnection connection = null;
        String content = "";
        try {
            URL address_url = new URL(url);
            connection = (HttpURLConnection) address_url.openConnection();
            connection.setRequestMethod("GET");
            //设置访问超时时间及读取网页流的超市时间,毫秒值
            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
            System.setProperty("sun.net.client.defaultReadTimeout", "30000");

            //after JDK 1.5
//            connection.setConnectTimeout(10000);
//            connection.setReadTimeout(10000);
            //得到访问页面的返回值
            int response_code = connection.getResponseCode();
            if (response_code == HttpURLConnection.HTTP_OK) {
                InputStream in = connection.getInputStream();
//                InputStreamReader reader = new InputStreamReader(in,charSet);
                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    content+=line;
                }
                return content;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(connection !=null){
                connection.disconnect();
            }
        }
        return "";
    }
    
    @SuppressWarnings("rawtypes")
    public static String getHttpContentByPost(String url, String charSet,Map<String, Object> requestParamsMap) {
        HttpURLConnection connection = null;
        DataOutputStream out = null;
        String content = "";
        StringBuffer params = new StringBuffer();  
        try {
        	
        	// 组织请求参数  
            Iterator it = requestParamsMap.entrySet().iterator();  
            while (it.hasNext()) {  
				Map.Entry element = (Map.Entry) it.next();  
                params.append(element.getKey());  
                params.append("=");  
                params.append(element.getValue());  
                params.append("&");  
            }  
            if (params.length() > 0) {  
                params.deleteCharAt(params.length() - 1);  
            }  
        	
            System.out.println("url>>>>>>>>>>" + url);
            System.out.println("params>>>>>>>>>>" + params);
            
            URL address_url = new URL(url);
            connection = (HttpURLConnection) address_url.openConnection();
            connection.setRequestMethod("POST");
            //设置访问超时时间及读取网页流的超市时间,毫秒值
            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
            System.setProperty("sun.net.client.defaultReadTimeout", "30000");

         // 设置通用的请求属性  
            connection.setRequestProperty("accept", "*/*");  
            connection.setRequestProperty("connection", "Keep-Alive");  
            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));  
            // 发送POST请求必须设置如下两行  
            connection.setDoOutput(true);  
            connection.setDoInput(true);  
            // 获取URLConnection对象对应的输出流  
            out = new DataOutputStream(connection.getOutputStream());
            // 发送请求参数 
            out.write(params.toString().getBytes("utf-8"));
            out.flush();
            out.close();
            //得到访问页面的返回值
            int response_code = connection.getResponseCode();
            
            System.out.println("response_code>>>>>" + response_code);
            
            if (response_code == HttpURLConnection.HTTP_OK) {
                InputStream in = connection.getInputStream();
//                InputStreamReader reader = new InputStreamReader(in,charSet);
                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    content+=line;
                }
                
                System.out.println("content>>>>>" + content);
                return content;
            }
            
            
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(connection !=null){
                connection.disconnect();
            }
        }
        return "";
    }
    
    public static String getHttpContentByPost(String url, String charSet,String params) {
        HttpURLConnection connection = null;
        String content = "";
        PrintWriter printWriter = null;
        try {

            URL address_url = new URL(url);
            connection = (HttpURLConnection) address_url.openConnection();
            connection.setRequestMethod("POST");
            //设置访问超时时间及读取网页流的超市时间,毫秒值
            System.setProperty("sun.net.client.defaultConnectTimeout","30000");
            System.setProperty("sun.net.client.defaultReadTimeout", "30000");

         // 设置通用的请求属性  
            connection.setRequestProperty("accept", "*/*");  
            connection.setRequestProperty("connection", "Keep-Alive");  
            connection.setRequestProperty("Content-Length", String.valueOf(params.length()));  
            // 发送POST请求必须设置如下两行  
            connection.setDoOutput(true);  
            connection.setDoInput(true);  
            // 获取URLConnection对象对应的输出流  
            printWriter = new PrintWriter(connection.getOutputStream());  
            // 发送请求参数  
            printWriter.write(params);  
            // flush输出流的缓冲  
            printWriter.flush();  
            //得到访问页面的返回值
            int response_code = connection.getResponseCode();
            if (response_code == HttpURLConnection.HTTP_OK) {
                InputStream in = connection.getInputStream();
//                InputStreamReader reader = new InputStreamReader(in,charSet);
                BufferedReader reader = new BufferedReader(new InputStreamReader(in, charSet));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    content+=line;
                }
                return content;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(connection !=null){
                connection.disconnect();
            }
        }
        return "";
    }

	/**
	 * 以http post方式请求
	 * @param url 请求地址
	 * @param data 请求参数
	 * @return
	 */
	public static String requestByPost(String url,String data){
		return requestByPost(url,charSet,data,connectTimeoutMs,readTimeoutMs);
	}
	
	/**
	 * 以http get方式请求
	 * @param url 请求地址
	 * @return
	 */
	public static String requestByGet(String url){
		return requestByGet(url,charSet,connectTimeoutMs,readTimeoutMs);
	}
	
	/**
	 * 以http post方式请求
	 * @param url 请求地址
	 * @param charSet 字符编码
	 * @param data 请求参数
	 * @param connectTimeoutMs 连接超时(毫秒)
	 * @param readTimeoutMs 数据读取超时(毫秒)
	 * @return
	 */
    public static String requestByPost(String url,String charSet,String data, int connectTimeoutMs, int readTimeoutMs){
    	try{
	        BasicHttpClientConnectionManager connManager;

	        connManager = new BasicHttpClientConnectionManager(
	                RegistryBuilder.<ConnectionSocketFactory>create()
	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
	                        .build(),
	                null,
	                null,
	                null
	        );

	        HttpClient httpClient = HttpClientBuilder.create()
					//取消HttpClient 设置超时后，若在设定的时间内没有返回数据，httpClient底层会重复请求
					.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
	                .setConnectionManager(connManager)
	                .build();

	        HttpPost httpPost = new HttpPost(url);

	        RequestConfig requestConfig = RequestConfig.custom()
					.setSocketTimeout(readTimeoutMs)
					.setConnectTimeout(connectTimeoutMs)
					.build();

	        httpPost.setConfig(requestConfig);

	        StringEntity postEntity = new StringEntity(data, charSet);
	        httpPost.addHeader("Content-Type", "text/xml");
	        httpPost.setEntity(postEntity);

	        HttpResponse httpResponse = httpClient.execute(httpPost);
	        HttpEntity httpEntity = httpResponse.getEntity();
	        return EntityUtils.toString(httpEntity, "UTF-8");
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    	return "";

    }
    
    /**
	 * 以http get方式请求
	 * @param url 请求地址
	 * @param charSet 字符编码
	 * @param connectTimeoutMs 连接超时(毫秒)
	 * @param readTimeoutMs 数据读取超时(毫秒)
	 * @return
	 */
    public static String requestByGet(String url,String charSet,int connectTimeoutMs, int readTimeoutMs){
    	try{
	        BasicHttpClientConnectionManager connManager;
	        
	        connManager = new BasicHttpClientConnectionManager(
	                RegistryBuilder.<ConnectionSocketFactory>create()
	                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
	                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
	                        .build(),
	                null,
	                null,
	                null
	        );
	
	        HttpClient httpClient = HttpClientBuilder.create()
	                .setConnectionManager(connManager)
	                .build();
	        
	        HttpGet httpGet = new HttpGet(url);
	        
	        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
	        httpGet.setConfig(requestConfig);	
	        httpGet.addHeader("Content-Type", "text/xml");
	
	        HttpResponse httpResponse = httpClient.execute(httpGet);
	        HttpEntity httpEntity = httpResponse.getEntity();
	        return EntityUtils.toString(httpEntity, "UTF-8");
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    	return "";

    }
    
    /**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr 提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			URL url = new URL(requestUrl);
			HttpURLConnection httpUrlConn = (HttpURLConnection)url.openConnection();

			if (requestUrl.startsWith("https")) {
				HttpsURLConnection httpsURLConnection = (HttpsURLConnection)httpUrlConn;

				// 创建SSLContext对象，并使用我们指定的信任管理器初始化
				TrustManager[] tm = { new MyX509TrustManager() };
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, tm, new java.security.SecureRandom());
				// 从上述SSLContext对象中得到SSLSocketFactory对象
				SSLSocketFactory ssf = sslContext.getSocketFactory();

				httpsURLConnection.setSSLSocketFactory(ssf);
			}

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			System.out.println("Weixin server connection timed out.");
		} catch (Exception e) {
			System.out.println("https request error:" +  e.getMessage());
		}
		return jsonObject;
	}

	public static InputStream downloadStream(String requestUrl){
		InputStream inputStream = null;

		try {
			URL url = new URL(requestUrl);
			HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

			if (requestUrl.startsWith("https")) {
				HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpUrlConn;

				// 创建SSLContext对象，并使用我们指定的信任管理器初始化
				TrustManager[] tm = {new MyX509TrustManager()};
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, tm, new java.security.SecureRandom());
				// 从上述SSLContext对象中得到SSLSocketFactory对象
				SSLSocketFactory ssf = sslContext.getSocketFactory();

				httpsURLConnection.setSSLSocketFactory(ssf);
			}

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			httpUrlConn.setRequestMethod("GET");
			httpUrlConn.connect();

			inputStream = httpUrlConn.getInputStream();
		}
		catch (Exception ex){
			System.out.println(ex.getMessage());
		}

		return inputStream;
	}

}
