package com.chinacreator.process.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HttpInvoke {
	
	protected static Logger log = Logger.getLogger(HttpInvoke.class);
	
	private static class TrustAnyTrustManager implements X509TrustManager {  
		     
	   public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		   
	   }  
	 
	   public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		   
	   }  
	 
	   public X509Certificate[] getAcceptedIssuers() {  
	       return new X509Certificate[]{};  
	   }  
	}  
	     
	private static class TrustAnyHostnameVerifier implements HostnameVerifier {  
		public boolean verify(String hostname, SSLSession session) {  
		     return true;  
		}  
	}
	
	/**
	 * 处理https请求，超时时间默认为30秒
	 * @param method
	 * @param url
	 * @param content
	 * @param reqProperty
	 * @return
	 * @throws Exception 
	 */
	public static String sendhttpsReq(String method, String url, String content, Map reqProperty) throws Exception{
		return sendhttpsReq(method, url, content, reqProperty, 0);
	}
	
	/**
	 * 处理https请求
	 * @param method
	 * @param url
	 * @param content
	 * @param reqProperty
	 * @param timeout 超时时间， 如果小于或等于0，给默认值30秒
	 * @return
	 * @throws Exception 
	 */
	public static String sendhttpsReq(String method, String url, String content, Map reqProperty, int timeout) throws Exception{
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		StringBuffer buffer = new StringBuffer();
    	HttpsURLConnection connection = null;
    	BufferedReader reader = null;
    	OutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
    	try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());  
			connection = (HttpsURLConnection) new URL(url).openConnection();
			connection.setSSLSocketFactory(sc.getSocketFactory());  
			connection.setHostnameVerifier(new TrustAnyHostnameVerifier());  
			connection.setRequestMethod(method);
			connection.setDoOutput(true);
			connection.setDoInput(true);
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			
			if(reqProperty != null && reqProperty.size()>0){
				Set keySet = reqProperty.keySet();
				Iterator iterator = keySet.iterator();
				String key = "";
				String value = "";
				while(iterator.hasNext()){
					key = (String)iterator.next(); 
					value = (String)reqProperty.get(key);
					connection.setRequestProperty(key, value);
				}
			}
			
			connection.connect();
			out = connection.getOutputStream();
			out.write(content.getBytes("UTF-8"));
			out.flush();
			
			if (200 != connection.getResponseCode()) {

			}else{
				inputStream = connection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream, "utf-8");
				reader = new BufferedReader(inputStreamReader);

				String line = "";
				while ((line = reader.readLine()) != null) {
					buffer.append(line);
				}
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
    }
	
	/** 
	 * 连接到服务器并获取数据，超时时间默认为30秒
	 * GET方式发起请求
	 * @param urlStr 请求URL
	 * @param content 请求报文
	 * @return
	 * @throws Exception 
	 */
	public static String sendHttpByGet(String urlStr, String content, Map reqProperty) throws Exception {
		return sendHttpByGet(urlStr, content, reqProperty, 0);
	}
	
	/** 
	 * 连接到服务器并获取数据
	 * GET方式发起请求
	 * @param urlStr 请求URL
	 * @param content 请求报文
	 * @return
	 * @throws Exception 
	 */
	public static String sendHttpByGet(String urlStr, String content, Map reqProperty, int timeout) throws Exception {
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		URL url = null;
		HttpURLConnection connection = null;
		StringBuffer buffer = new StringBuffer();
    	BufferedReader reader = null;
    	OutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		try {
			url = new URL(urlStr+"/"+URLEncoder.encode(content,"UTF-8"));	
			connection = (HttpURLConnection) url.openConnection();
			
			if(reqProperty != null && reqProperty.size()>0){
				Set keySet = reqProperty.keySet();
				Iterator iterator = keySet.iterator();
				String key = "";
				String value = "";
				while(iterator.hasNext()){
					key = (String)iterator.next(); 
					value = (String)reqProperty.get(key);
					connection.setRequestProperty(key, value);
				}
			}
			
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			connection.connect();

			if (200 != connection.getResponseCode()) {
			   
			}else{
				inputStream = connection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream, "utf-8");
				reader = new BufferedReader(inputStreamReader);

				String line = "";
				while ((line = reader.readLine()) != null) {
					buffer.append(line);
				}
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
	}
	
	/** 
	 * 连接到服务器并获取数据
	 * GET方式发起请求
	 * @param urlStr 请求URL
	 * @param content 请求报文
	 * @return
	 * @throws Exception 
	 */
	public static String sendHttpByGet(String urlStr, int timeout) throws Exception {
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		URL url = null;
		HttpURLConnection connection = null;
		StringBuffer buffer = new StringBuffer();
    	BufferedReader reader = null;
    	OutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		try {
			url = new URL(urlStr);	
			connection = (HttpURLConnection) url.openConnection();
			
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			connection.connect();

			if (200 != connection.getResponseCode()) {
			   
			}else{
				inputStream = connection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream, "utf-8");
				reader = new BufferedReader(inputStreamReader);

				String line = "";
				while ((line = reader.readLine()) != null) {
					buffer.append(line);
				}
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
	}
	
	/**
	 * 连接到服务器并获取数据，超时时间默认为30秒
	 * POST方式发起请求
	 * @param method 请求方法，POST/PUT 
	 * @param urlStr 请求URL
	 * @param content 请求报文
	 * @param reqProperty 请求属性
	 * @return
	 * @throws Exception 
	 */
	public static String sendHttpByPost(String method, String urlStr, String content, Map reqProperty) throws Exception{
		return sendHttpByPost(method, urlStr, content, reqProperty, 0);
	}
	
	/**
	 * 连接到服务器并获取数据
	 * POST方式发起请求
	 * @param method 请求方法，POST/PUT 
	 * @param urlStr 请求URL
	 * @param content 请求报文
	 * @param reqProperty 请求属性
	 * @param timeout 超时时间，毫秒	 
	 * @return
	 * @throws Exception 
	 */
	public static String sendHttpByPost(String method, String urlStr, String content, Map reqProperty, int timeout) throws Exception{
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		URL url = null;
		HttpURLConnection connection = null;
		StringBuffer buffer = new StringBuffer();
    	BufferedReader reader = null;
    	DataOutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		try {
			url = new URL(urlStr);	
			connection = (HttpURLConnection) url.openConnection();
			if(reqProperty != null && reqProperty.size()>0){
				Set keySet = reqProperty.keySet();
				Iterator iterator = keySet.iterator();
				String key = "";
				String value = "";
				while(iterator.hasNext()){
					key = (String)iterator.next(); 
					value = (String)reqProperty.get(key);
					connection.setRequestProperty(key, value);
				}
			}
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestMethod(method);
			connection.setUseCaches(false);
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			connection.connect();

			out = new DataOutputStream(connection.getOutputStream());
			out.write(content.getBytes("utf-8"));
			out.flush();
			out.close();

			inputStream = connection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			reader = new BufferedReader(inputStreamReader);
			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			
			reader.close();			
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
	}
	
	
	/**
	 * 处理https请求
	 * @param method
	 * @param url
	 * @param content
	 * @param reqProperty
	 * @param timeout 超时时间， 如果小于或等于0，给默认值30秒
	 * @param tls TLS协议，为空是使用SSL
	 * @return
	 * @throws Exception 
	 */
	public static String sendhttpsReq(String method, String url, String content, Map reqProperty, int timeout, String tls) throws Exception{
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		if(tls == null || "".equals(tls)){
			tls = "SSL";
		}
		StringBuffer buffer = new StringBuffer();
    	HttpsURLConnection connection = null;
    	BufferedReader reader = null;
    	OutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
    	try {
    		log.info("invokeurl=>"+url+"，reqProperty=>"+reqProperty+"，content=>"+content);
    		
			SSLContext sc = SSLContext.getInstance(tls);
			sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());  
			connection = (HttpsURLConnection) new URL(url).openConnection();
			connection.setSSLSocketFactory(sc.getSocketFactory());  
			connection.setHostnameVerifier(new TrustAnyHostnameVerifier());  
			connection.setRequestMethod(method);
			connection.setDoOutput(true);
			connection.setDoInput(true);
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			
			if(reqProperty != null && reqProperty.size()>0){
				Set keySet = reqProperty.keySet();
				Iterator iterator = keySet.iterator();
				String key = "";
				String value = "";
				while(iterator.hasNext()){
					key = (String)iterator.next(); 
					value = (String)reqProperty.get(key);
					connection.setRequestProperty(key, value);
				}
			}else{
				//默认设置
				if("GET".equals(method)){
					connection.setRequestProperty("Content-type", "text/plain");
				}else{
					connection.setRequestProperty("Content-type", "application/json;charset=utf-8");
				}
			}
			
			connection.connect();
			
			//参数不为空
			if(!StringUtils.isEmpty(content)){
				out = connection.getOutputStream();
				out.write(content.getBytes("UTF-8"));
				out.flush();
			}

			inputStream = connection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			reader = new BufferedReader(inputStreamReader);

			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
    }
	
	/**
	 * 把map转换为url地址Params
	 * @param map 存储参数的map
	 * @return  返回完整的url地址
	 */
	public static String mapToUrl(Map<String,String> map){
		StringBuilder param = new StringBuilder("");
		if (map == null) {
			return "";
		}
		for(Map.Entry<String,String> entry: map.entrySet()){
			String key =  entry.getKey();
			String val =  entry.getValue();
			param.append(key).append("=").append(val).append("&");
		}
		//删去最后的&
		if (param.toString().endsWith("&")) {
			param.deleteCharAt(param.length() - 1);
		}
		return param.toString();
	}
	
	/**
	 * 处理https请求，非200也返回信息
	 * @param method
	 * @param url
	 * @param content GET提交时，此参数可以为空
	 * @param reqProperty GET提交时，此参数可以为空
	 * @param timeout 超时时间， 如果小于或等于0，给默认值30秒
	 * @param tls TLS协议，为空是使用SSL
	 * @return
	 * @throws Exception 
	 */
	public static String sendhttpsReqAll(String method, String url, String content, Map reqProperty, int timeout, String tls) throws Exception{
		if(timeout <= 0){
			timeout = 30000; //如果超时时间小于或等于0，给默认值30秒
		}
		if(tls == null || "".equals(tls)){
			tls = "SSL";
		}
		StringBuffer buffer = new StringBuffer();
    	HttpsURLConnection connection = null;
    	BufferedReader reader = null;
    	OutputStream out = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
    	try {
    		log.info("invokeurl=>"+url+"，reqProperty=>"+reqProperty+"，content=>"+content);
    		
			SSLContext sc = SSLContext.getInstance(tls);
			sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());  
			connection = (HttpsURLConnection) new URL(url).openConnection();
			connection.setSSLSocketFactory(sc.getSocketFactory());  
			connection.setHostnameVerifier(new TrustAnyHostnameVerifier());  
			connection.setRequestMethod(method);
			connection.setDoOutput(true);
			connection.setDoInput(true);
			//设置超时时间为30秒
			connection.setConnectTimeout(timeout);
			connection.setReadTimeout(timeout);
			
			if(reqProperty != null && reqProperty.size()>0){
				Set keySet = reqProperty.keySet();
				Iterator iterator = keySet.iterator();
				String key = "";
				String value = "";
				while(iterator.hasNext()){
					key = (String)iterator.next(); 
					value = (String)reqProperty.get(key);
					connection.setRequestProperty(key, value);
				}
			}
			
			connection.connect();
			if(!StringUtils.isEmpty(content)){
				out = connection.getOutputStream();
				out.write(content.getBytes("UTF-8"));
				out.flush();
			}
			
			int responseCode = connection.getResponseCode();
			log.info("responseCode:"+responseCode);
			//小于400，从inputStream获取响应数据
			if(responseCode < HttpsURLConnection.HTTP_BAD_REQUEST){
				inputStream = connection.getInputStream();
			}else{//小于或等于400，从errorStream获取响应数据
				inputStream = connection.getErrorStream();
			}
			//inputStream = connection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			reader = new BufferedReader(inputStreamReader);

			String line = "";
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
			log.error("调HTTP请求出现IO异常："+e.getMessage());
			throw e;
		} catch (Exception e){
			e.printStackTrace();
			log.error("调HTTP请求出现异常："+e.getMessage());
			throw e;
		} finally {
			if(inputStreamReader != null){
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					inputStreamReader = null;
					log.error("释放inputStreamReader异常："+e.getMessage());
				}
			}
			if(inputStream != null){
				try {
					inputStream.close();
				} catch (IOException e) {
					inputStream = null;
					log.error("释放inputStream异常："+e.getMessage());
				}
			}
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					out = null;
					log.error("释放out异常："+e.getMessage());
				}
			}
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					reader = null;
					log.error("释放reader异常："+e.getMessage());
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}
		return buffer.toString();
    }
}
