package com.cool.bang.common.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
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.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Java发送GET、POST请求，可以传参
 * 使用httpClient实现；
 * 依赖包：org.apache.httpcomponents > httpclient
 * @author JK.Sun
 * @version 2020-08-28
 */
public class Client {

	/**
     * GET请求（地址拼接参数）
     */
    public static String get(String url) {
        String result = null;
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        try {
            response = httpClient.execute(get);
            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * get请求，参数放在map里
     * @param url 请求地址
     * @param map 参数map
     * @return 响应
     */
    public static String getMap(String url, Map<String,String> heads, Map<String,String> map) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for(Map.Entry<String,String> entry : map.entrySet()){
            pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            builder.setParameters(pairs);
            HttpGet get = new HttpGet(builder.build());

            get.addHeader("Content-Type", "text/html; charset=UTF-8");
            for(Map.Entry<String,String> entry : heads.entrySet()) {
            	get.addHeader(entry.getKey(), entry.getValue());
            }

            response = httpClient.execute(get);

            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
                if(response != null)
                {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * get请求，参数放在map里
     * @param url 请求地址
     * @param map 参数map
     * @return 响应
     */
    public static boolean getMapDown(String url, Map<String,String> heads, Map<String,String> map, String filePath) {
        boolean result = false;

        CloseableHttpClient httpClient = HttpClients.createDefault();

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for(Map.Entry<String,String> entry : map.entrySet()){
            pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            builder.setParameters(pairs);
            HttpGet get = new HttpGet(builder.build());

            get.addHeader("Content-Type", "application/pdf; charset=UTF-8");
            for(Map.Entry<String,String> entry : heads.entrySet()) {
            	get.addHeader(entry.getKey(), entry.getValue());
            }

            response = httpClient.execute(get);
            InputStream inputStream = response.getEntity().getContent();
            int index;
            byte[] bytes = new byte[1024];
            FileOutputStream downloadFile = new FileOutputStream(filePath);
            while ((index = inputStream.read(bytes)) != -1) {
                downloadFile.write(bytes, 0, index);
                downloadFile.flush();
            }
            downloadFile.close();
            inputStream.close();
            result = true;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
                if(response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 发送post请求，参数用map接收
     * @param url 地址
     * @param map 参数
     * @return 返回值
     */
    public static String postMap(String url, Map<String,String> map) {
    	System.out.println(">> PostMap发送请求...");
    	System.out.println(">> URL="+url);
    	System.out.println(">> MAP="+map);

        String result = null;

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for(Map.Entry<String,String> entry : map.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }

        CloseableHttpResponse response = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(pairs,"UTF-8"));
            response = httpClient.execute(post);
            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }

            System.out.println(">> PostMap返回数据：" + result);
            return result;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {   //
                httpClient.close();
                if(response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 发送post请求，参数用map接收
     * @param url 地址
     * @param map 参数
     * @return 返回值
     */
    public static String postMap(String url, Map<String,String> heads, Map<String,String> map) {
    	System.out.println(">> PostMap发送请求...");
    	System.out.println(">> URL="+url);
    	System.out.println(">> HEAD="+heads);
    	System.out.println(">> MAP="+map);

        String result = null;

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);

        for(Map.Entry<String,String> entry : heads.entrySet()) {
        	post.addHeader(entry.getKey(), entry.getValue());
        }

        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for(Map.Entry<String,String> entry : map.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }

        CloseableHttpResponse response = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(pairs,"UTF-8"));
            response = httpClient.execute(post);

            if( response != null ){
            	System.out.println(response.getStatusLine().getStatusCode());
            }

            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }

            System.out.println(">> PostMap返回数据：" + result);
            return result;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
                if(response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }




    /** * 发送post请求 * @param json * @param URL * @return */
    public static String sendPost(Map<String,String> map, String URL) {

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(URL);
        post.setHeader("Content-Type", "application/json");
        post.addHeader("Authorization", "Basic YWRtaW46");
        String result;
        try {
            JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(map));
            System.out.println("请求参数"+json);
            StringEntity s = new StringEntity(json.toString(), "utf-8");
            s.setContentType(new BasicHeader("Accept",
                    "application/json"));
            post.setEntity(s);
            // 发送请求
            HttpResponse httpResponse = client.execute(post);
            // 获取响应输入流
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null)
                strber.append(line + "\n");
            inStream.close();
            result = strber.toString();
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                System.out.println("请求服务器成功"+result);
            } else {
                System.out.println("请求服务端失败"+result);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }


    /**
     * 发送post请求，参数用map接收
     * @param url 地址
     * @param map 参数
     * @return 返回值
     */
    public static String postMap(String url, Map<String,String> heads, Map<String,String> map, Map<String, File> files) throws Exception{
    	System.out.println(">> PostMap发送请求...");
    	System.out.println(">> URL="+url);
    	System.out.println(">> HEAD="+heads);
    	System.out.println(">> MAP="+map);
    	System.out.println(">> files="+files);

        String result = null;

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);

        for(Map.Entry<String,String> entry : heads.entrySet()) {
        	post.addHeader(entry.getKey(), entry.getValue());
        }

        CloseableHttpResponse response = null;
        try {
        	MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        	//设置浏览器兼容模式
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //设置请求的编码格式
            builder.setCharset(Consts.UTF_8);
            //builder.setContentType(ContentType.MULTIPART_FORM_DATA);
            ContentType strContent=ContentType.create("text/plain", StandardCharsets.UTF_8);

            for(Map.Entry<String,File> entry : files.entrySet()) {
	        	File file = entry.getValue();
	        	builder.addBinaryBody(entry.getKey(), file);
	        }
	        for(Map.Entry<String,String> entry : map.entrySet()) {
	        	builder.addTextBody(entry.getKey(), entry.getValue(), strContent);
	        }

	        HttpEntity httpEntity = builder.build();
	        post.setEntity(httpEntity);

            response = httpClient.execute(post);

            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }

            System.out.println(">> PostMap返回数据：" + result);
            return result;

        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String doHttpPost(String url, Map<String, String> headerMap, Map<String, String> paramMap) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
        	httpClient =HttpClientBuilder.create().build();
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
            httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            //希望接收数据格式为json
            httpPost.setHeader("Accept","application/json");
            //请求头，设置成json,接收端请设置成@RequestBody
            //httpPost.setHeader("Content-Type", ContentTypeJson);
            if (headerMap != null) {
                Iterator<Map.Entry<String, String>> iteratorHeader = headerMap.entrySet().iterator();
                while (iteratorHeader.hasNext()) {
                    Map.Entry<String, String> elem = iteratorHeader.next();
                    if(!elem.getKey().equalsIgnoreCase("Content-Length")) {
                    	httpPost.addHeader(elem.getKey(), elem.getValue());
                    }
                }
            }
            //设置请求参数
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            if (paramMap != null) {
                Iterator<Map.Entry<String, String>> iteratorParam = paramMap.entrySet().iterator();
                while (iteratorParam.hasNext()) {
                    Map.Entry<String, String> elem = iteratorParam.next();
                    nameValuePairs.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
                }
            }

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,Charset.forName("utf-8")));
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null && HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {

                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

	/**
     * post请求，参数为json字符串
     * @param url 请求地址
     * @param jsonString json字符串
     * @return 响应
     */
    public static String postJson(String url, Map<String,String> heads, String jsonString) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        System.out.println(">>>>>>>>>>>>>>>> url: "+ url);
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse response = null;
        //希望接收数据格式为json
        post.setHeader("Content-Type","application/json");
        try {
        	for(Map.Entry<String,String> entry : heads.entrySet()) {
            	post.addHeader(entry.getKey(), entry.getValue());
            }
            post.setEntity(new ByteArrayEntity(jsonString.getBytes("UTF-8")));
            response = httpClient.execute(post);
            if(response != null && response.getStatusLine().getStatusCode() == 200)
            {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
                if(response != null)
                {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * post请求，参数为json字符串
     * @param url 请求地址
     * @param jsonString json字符串
     * @return 响应
     */
    public static String postJson(String url, String jsonString) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            post.setEntity(new ByteArrayEntity(jsonString.getBytes("UTF-8")));
            response = httpClient.execute(post);
            if(response != null && response.getStatusLine().getStatusCode() == 200)
            {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
                if(response != null)
                {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

	private static String entityToString(HttpEntity entity) throws IOException {
        String result = null;
        if(entity != null)
        {
            long lenth = entity.getContentLength();
            if(lenth != -1 && lenth < 2048)
            {
                result = EntityUtils.toString(entity,"UTF-8");
            }else {
                InputStreamReader reader1 = new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8);
                CharArrayBuffer buffer = new CharArrayBuffer(2048);
                char[] tmp = new char[1024];
                int l;
                while((l = reader1.read(tmp)) != -1) {
                    buffer.append(tmp, 0, l);
                }
                result = buffer.toString();
            }
        }
        return result;
    }

    public static void main(String[] args) {
        /*String url = "http://222.134.131.130:9182/v2/document/createbyfile";
        Map<String,String> head = new HashMap<>();
        head.put("x-qys-signature","706f6cd05da6ec8cc22a4b08bf04a749");
        head.put("x-qys-accesstoken","wtyszwWHhA");
        head.put("x-qys-timestamp","0");
        Map<String,String> map = new HashMap<>();
        map.put("width","210");
        map.put("title","监管协议C20211109000160");
        map.put("fileType","pdf");
        map.put("height","297");
        Map<String,File> files = new HashMap<>();
        File file = new File("d:\\gftFiles\\2021\\11\\09\\T4a9cd843c0cb4d85881a9760b024e1e8P.pdf");
        files.put("file",file);
        postMap(url,head,map,files);*/
        //System.out.println(MD5Util.MD5("ROrnvDsAVO"+"k6zoiqopZF54vHdD1J2G5PaJRBavSu"+"0"));
    }

}
