/**
 * @Company: 北京慧点科技有限公司 | www.smartdot.com.cn
 * @Copyright 1998-2020 © Smartdot Technologies Co., Ltd.
 */
package com.search.supersearch.util;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
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.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
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.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 会议与OA进行HTTP请求-工具类
 *
 * @author <a href="mailto:litw@smartdot.com">litw</a>
 * @version 1.0 - 2020-06-7 14点23分
 * @class: HttpClientUtils
 * @date 2020-07-31 21:42:27
 * @see
 */
public class HttpClientUtils {

    static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    /**
     * GET请求
     *
     * @param url
     * @param parameters
     * @return
     * @author shijunbao
     * @since 1.0, Aug 5, 2020
     */
    public static String get(String url, Map<String, String> parameters) {
        String entityStr = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            // 设置参数
            List<NameValuePair> nameValuePairs = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                nameValuePairs.add(nameValuePair);
            }
            uriBuilder.setParameters(nameValuePairs);
            // GET请求
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            entityStr = httpClientExecute(httpGet);
        } catch (URISyntaxException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        }
        return entityStr;
    }

    /**
     * POST请求
     *
     * @param url
     * @param parameters
     * @return
     * @author shijunbao
     * @since 1.0, Aug 5, 2020
     */
    public static String post(String url, Map<String, String> parameters) {
        String entityStr = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            // 设置参数
            List<NameValuePair> nameValuePairs = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                nameValuePairs.add(nameValuePair);
            }
            uriBuilder.setParameters(nameValuePairs);
            // POST请求
            HttpPost httpPost = new HttpPost(uriBuilder.build());
            entityStr = httpClientExecute(httpPost);
        } catch (URISyntaxException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        }
        return entityStr;
    }

    public static String post(String url, Map<String, String> parameters, Map<String, File> files) {
        String entityStr = null;
        HttpPost httppost = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        if (parameters != null) {
            parameters.forEach((parameterName, parameterValue) -> {
                StringBody stringBody = new StringBody(parameterValue, ContentType.TEXT_PLAIN);
                builder.addPart(parameterName, stringBody);
            });
        }

        if (files != null) {
            files.forEach((fieldName, needUploadFile) -> {
                FileBody fileBody = new FileBody(needUploadFile);
                builder.addPart(fieldName, fileBody);
            });
        }

        HttpEntity requestEntity = builder.build();
        httppost.setEntity(requestEntity);
        entityStr = httpClientExecuteWithMultipart(httppost);
        return entityStr;
    }

    /**
     * POST请求
     *
     * @param url
     * @param jsonParameters
     * @return
     * @author shijunbao
     * @since 1.0, Aug 5, 2020
     */
    public static String post(String url, String jsonParameters) {
        String entityStr = null;
        try {
            // POST请求
            HttpPost httpPost = new HttpPost(url);
            // 设置参数
            StringEntity stringEntity = new StringEntity(jsonParameters, ContentType.create("text/json", "UTF-8"));
            httpPost.setEntity(stringEntity);
            entityStr = httpClientExecute(httpPost);
        } catch (ParseException e) {
            logger.error("解析错误，请求失败!");
            e.printStackTrace();
        }
        return entityStr;
    }

    /**
     * httpClientExecute
     *
     * @param request
     * @return
     * @author shijunbao
     * @since 1.0, Aug 8, 2020
     */
    public static String httpClientExecute(final HttpUriRequest request) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            request.addHeader("Content-Type", "application/json");
            response = httpClient.execute(request);
            if (response.getStatusLine().toString().indexOf("200") < 0) {
                logger.error("请求地址失败！错误代码：" + response.getStatusLine().toString());
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            EntityUtils.consume(response.getEntity());
            return result;
        } catch (ClientProtocolException e) {
            logger.error("Http协议出现问题，请求失败!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("IO异常，请求失败!");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    logger.error("释放连接出错!");
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String httpClientExecuteWithMultipart(final HttpUriRequest request) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(request);
            if (response.getStatusLine().toString().indexOf("200") < 0) {
                logger.error("请求地址失败！错误代码：" + response.getStatusLine().toString());
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            EntityUtils.consume(response.getEntity());
            return result;
        } catch (ClientProtocolException e) {
            logger.error("Http协议出现问题，请求失败!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("IO异常，请求失败!");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    logger.error("释放连接出错!");
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String getResponse(String url, Map<String, String> parameters, String appKey, String appSecrty) {
//        String post = HttpClientUtils.post(url, parameters);
        String entityStr = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            // 设置参数
            List<NameValuePair> nameValuePairs = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                nameValuePairs.add(nameValuePair);
            }
            uriBuilder.setParameters(nameValuePairs);
            // POST请求
            HttpPost httpPost = new HttpPost(uriBuilder.build());
            httpPost.addHeader("Content-Appkey", appKey);
            httpPost.addHeader("Content-Signature", appSecrty);
            entityStr = httpClientExecute(httpPost);
        } catch (URISyntaxException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        }
        return entityStr;


    }

    public static String getResponseUplod(String url, Map<String, String> parameters, String appKey, String signed) {
        String entityStr = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            // 设置参数
            List<NameValuePair> list = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            // POST请求
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, "UTF-8");
            httpPost.setEntity(formEntity);
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.addHeader("Content-Signature", signed);
            httpPost.addHeader("Content-Appkey", appKey);

            entityStr = httpClientExecuteUplod(httpPost);
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        }
        return entityStr;


    }

    public static String getResponseUplod(String url, Map<String, String> parameters) {
        String entityStr = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            // 设置参数
            List<NameValuePair> list = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            // POST请求
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, "UTF-8");
            httpPost.setEntity(formEntity);
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

            entityStr = httpClientExecuteUplod(httpPost);
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        }
        return entityStr;


    }

    public static String httpClientExecuteUplod(final HttpUriRequest request) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(request);
            if (response.getStatusLine().toString().indexOf("200") < 0) {
                logger.error("请求地址失败！错误代码：" + response.getStatusLine().toString());
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            EntityUtils.consume(response.getEntity());
            return result;
        } catch (ClientProtocolException e) {
            logger.error("Http协议出现问题，请求失败!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("IO异常，请求失败!");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    logger.error("释放连接出错!");
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * GET请求
     *
     * @param url
     * @param parameters
     * @return
     * @author shijunbao
     * @since 1.0, Aug 5, 2020
     */
    public static String getStrEncode(String url, Map<String, String> parameters) {
        String entityStr = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            // 设置参数
            List<NameValuePair> nameValuePairs = new LinkedList<NameValuePair>();
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                nameValuePairs.add(nameValuePair);
            }
            uriBuilder.setParameters(nameValuePairs);
            // GET请求
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            entityStr = httpClientExecuteStrEncode(httpGet);
        } catch (URISyntaxException e) {
            logger.error("URI解析异常，请求地址失败 ： " + url);
            e.printStackTrace();
        } catch (ParseException e) {
            logger.error("解析错误，请求地址失败!");
            e.printStackTrace();
        }
        return entityStr;
    }

    /**
     * httpClientExecute
     *
     * @param request
     * @return
     * @author shijunbao
     * @since 1.0, Aug 8, 2020
     */
    public static String httpClientExecuteStrEncode(final HttpUriRequest request) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            request.addHeader("Content-Type", "application/json");
            response = httpClient.execute(request);
            if (response.getStatusLine().toString().indexOf("200") < 0) {
                logger.error("请求地址失败！错误代码：" + response.getStatusLine().toString());
            }
            InputStream inputStream = response.getEntity().getContent();
            BufferedReader bufferedInputStrea = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
            StringBuilder stringBuilder = new StringBuilder();
            String temp;
            while ((temp = bufferedInputStrea.readLine()) != null) {
                stringBuilder.append(temp + "\n");
            }
            return stringBuilder.toString();
        } catch (ClientProtocolException e) {
            logger.error("Http协议出现问题，请求失败!");
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("IO异常，请求失败!");
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    logger.error("释放连接出错!");
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        String url = "http://localhost:8080/-app-/api/xcoa-mobile/v1/iammodelmaintain/getModelList";
        Map<String, String> map = new HashMap();
        map.put("account", "hdadmin");
        String s = get(url, map);
        System.out.println(s);
    }

    /**
     * @param strUrl
     * @return
     */
    public InputStream getInputStreamByUrl(String strUrl) {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(strUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(20 * 1000);
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(conn.getInputStream(), output);
            return new ByteArrayInputStream(output.toByteArray());
        } catch (Exception e) {
            logger.error("getInputStreamByUrl 异常,exception is {}", e);
        } finally {
            try {
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (Exception e) {
            }
        }
        return null;
    }
}
