package com.ssj.framework.core.util;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 类名称：Remote<br>
 * 类描述： HttpClient 远程请求访问类<br>
 * @version v1.0
 * 
 */
public class HttpRemote {

    private static final Logger logger = LoggerFactory.getLogger(HttpRemote.class);
    

    /**
     * 以Post方法访问 字符串拼接到后面的URL
     * @param url 请求地址
     * @param argsMap 携带的参数
     * @return String 返回结果
     * @throws Exception
     */
    public static String POSTMethod(String url, Map<String, Object> argsMap) throws Exception {
        byte[] dataByte = null;

        // DefaultHttpClient已作废
        // HttpClient httpClient=new DefaultHttpClient();

        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient httpClient = httpClientBuilder.build();

        HttpPost httpPost = new HttpPost(url);
        // 设置参数
        UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(setHttpParams(argsMap), "UTF-8");
        logger.debug("POST请求参数为：" + IOUtils.toString(encodedFormEntity.getContent()));
        httpPost.setEntity(encodedFormEntity);
        // 执行请求
        HttpResponse httpResponse = httpClient.execute(httpPost);
        // 获取返回的数据
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            byte[] responseBytes = getData(httpEntity);
            dataByte = responseBytes;
            httpPost.abort();
        }
        // 将字节数组转换成为字符串
        String result = bytesToString(dataByte);
        return result;
    }
    /**
     * header 'Content-Type: application/json' --header 'Accept: application/json'
     * 以body方式提交json数据
    * @param url
    * @param body
    * @return
    * @throws Exception
    * 创建人：ZhangCaibao 
    * 2018年4月24日 下午2:22:14 
    * @String
     */
    public static String POSTMethod(String url, String body) throws Exception {
    	byte[] dataByte = null;
    	
    	
    	// 创建HttpClientBuilder
    	HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
    	// HttpClient
    	CloseableHttpClient httpClient = httpClientBuilder.build();
    	
    	HttpPost httpPost = new HttpPost(url);
    	httpPost.addHeader("Content-Type", "application/json");
    	// 设置参数
    	logger.debug("POST请求参数为：" + body);
    	httpPost.setEntity(new StringEntity(body, "utf-8"));
    	// 执行请求
    	HttpResponse httpResponse = httpClient.execute(httpPost);
    	// 获取返回的数据
    	HttpEntity httpEntity = httpResponse.getEntity();
    	if (httpEntity != null) {
    		byte[] responseBytes = getData(httpEntity);
    		dataByte = responseBytes;
    		httpPost.abort();
    	}
    	// 将字节数组转换成为字符串
    	String result = bytesToString(dataByte);
    	return result;
    }

    /**
     * iopooooooliil 以Get方法访问
     * @param url 请求地址
     * @return String
     * @throws Exception
     */
    public static String GETMethod(String url, Map<String, Object> argsMap) throws Exception {
        byte[] dataByte = null;
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient httpClient = httpClientBuilder.build();
        // 为GET请求链接构造参数
        url = formatGetParameter(url, argsMap);
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Content-Type", "application/json");
        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            byte[] responseBytes = getData(httpEntity);
            dataByte = responseBytes;
            httpGet.abort();
        }
        // 将字节数组转换成为字符串
        String result = bytesToString(dataByte);
        return result;
    }

    /**
     * 以Put方法访问
     * @param url 请求地址
     * @param argsMap 携带的参数
     * @return String
     * @throws Exception
     */
    public static String PUTMethod(String url, Map<String, Object> argsMap) throws Exception {
        byte[] dataByte = null;
        // 创建HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient httpClient = httpClientBuilder.build();
        HttpPut httpPut = new HttpPut(url);
        // 设置参数
        UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(setHttpParams(argsMap), "UTF-8");
        httpPut.setEntity(encodedFormEntity);
        // 执行请求
        HttpResponse httpResponse = httpClient.execute(httpPut);
        // 获取返回的数据
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            byte[] responseBytes = getData(httpEntity);
            dataByte = responseBytes;
            httpPut.abort();
        }
        // 将字节数组转换成为字符串
        String result = bytesToString(dataByte);
        return result;
    }

    /**
     * 构造GET请求地址的参数拼接
     * @param url
     * @param argsMap
     * @return String
     */
    private static String formatGetParameter(String url, Map<String, Object> argsMap) {
        if (url != null && url.length() > 0) {
            if (!url.endsWith("?")) {
                url = url + "?";
            }

            if (argsMap != null && !argsMap.isEmpty()) {
                Set<Entry<String, Object>> entrySet = argsMap.entrySet();
                Iterator<Entry<String, Object>> iterator = entrySet.iterator();
                while (iterator.hasNext()) {
                    Entry<String, Object> entry = iterator.next();
                    if (entry != null) {
                        String key = entry.getKey();
                        String value = (String) entry.getValue();
                        url = url + key + "=" + value;
                        if (iterator.hasNext()) {
                            url = url + "&";
                        }
                    }
                }
            }
        }
        return url;
    }

    /**
     * 获取数据
     * @param httpEntity
     * @return
     * @throws Exception
     */
    private static byte[] getData(HttpEntity httpEntity) throws Exception {
        BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bufferedHttpEntity.writeTo(byteArrayOutputStream);
        byte[] responseBytes = byteArrayOutputStream.toByteArray();
        return responseBytes;
    }

    /**
     * 设置HttpPost请求参数
     * @param argsMap
     * @return BasicHttpParams
     */
    private static List<BasicNameValuePair> setHttpParams(Map<String, Object> argsMap) {
        List<BasicNameValuePair> nameValuePairList = new ArrayList<BasicNameValuePair>();
        // 设置请求参数
        if (argsMap != null && !argsMap.isEmpty()) {
            Set<Entry<String, Object>> set = argsMap.entrySet();
            Iterator<Entry<String, Object>> iterator = set.iterator();
            while (iterator.hasNext()) {
                Entry<String, Object> entry = iterator.next();
                String key = entry.getKey();
                String value = CastUtil.castString(entry.getValue());
                BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, value);
                nameValuePairList.add(basicNameValuePair);
            }
        }
        return nameValuePairList;
    }

    /**
     * 将字节数组转换成字符串
     * @param bytes
     * @return
     * @throws UnsupportedEncodingException
     */
    private static String bytesToString(byte[] bytes) throws UnsupportedEncodingException {
        if (bytes != null) {
            String returnStr = new String(bytes, "utf-8");
            return returnStr;
        }
        return null;
    }
}
