package com.pwt.common.utils.http;

import org.apache.http.HttpEntity;
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.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class HttpClientUtil {

    /**
     * 连接超时时间
     */
    private static final int CONNECT_TIME_OUT = 5000;

    /**
     * 请求超时时间
     */
    private static final int CONNECT_REQUEST_TIME_OUT = 5000;

    /**
     * socket读写超时时间
     */
    private static final int SOCKET_TIME_OUT = 5000;

    /**
     * 字符集
     */
    private static final String UTF8 = "utf-8";

    /**
     * 最大字节数
     */
    private static final int BYTE_ARRAY_LENGTH = 1048576;

    public static String get(String url)
    {
        return get(url, null);
    }

    public static String get(String url, Map<String, String> headers)
    {
        HttpGet get = new HttpGet(url);
        RequestConfig config = RequestConfig
                .custom()
                .setConnectTimeout(CONNECT_TIME_OUT)
                .setConnectionRequestTimeout(CONNECT_REQUEST_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setRedirectsEnabled(true)
                .build();
        get.setConfig(config);
        return getRespString(get, headers);
    }

    public static String post(String url)
    {
        return post(url, null, null);
    }

    public static String post(String url, Map<String, String> params)
    {
        return post(url, null, params);
    }

    public static String post(String url, Map<String, String> headers, Map<String, String> params)
    {
        HttpPost post = new HttpPost(url);
        RequestConfig config = RequestConfig
                .custom()
                .setConnectTimeout(CONNECT_TIME_OUT)
                .setConnectionRequestTimeout(CONNECT_REQUEST_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setRedirectsEnabled(true)
                .build();
        post.setConfig(config);
        if (params != null && params.size() > 0)
        {
            post.setEntity(getHttpEntity(params));
        }
        return getRespString(post, headers);
    }

    public static String postJson(String url, String json)
    {
        return postJson(url, null, json);
    }

    public static String postJson(String url, Map<String, String> headers, String json)
    {
        HttpPost post = new HttpPost(url);
        RequestConfig config = RequestConfig
                .custom()
                .setConnectTimeout(CONNECT_TIME_OUT)
                .setConnectionRequestTimeout(CONNECT_REQUEST_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT)
                .setRedirectsEnabled(true)
                .build();
        post.setConfig(config);
        post.setHeader("Content-type", "application/json");
        post.setEntity(new StringEntity(json, UTF8));
        return getRespString(post, headers);
    }

    private static HttpEntity getHttpEntity(Map<String, String> params)
    {
        UrlEncodedFormEntity urlEncodedFormEntity = null;
        List<BasicNameValuePair> pairs = new ArrayList<>();
        for (Map.Entry<String, String> entry : params.entrySet())
        {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        // HttpEntity entity = null;
        try
        {
            urlEncodedFormEntity = new UrlEncodedFormEntity(pairs, UTF8);
        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        return urlEncodedFormEntity;
    }

    private static void setHeaders(HttpUriRequest request, Map<String, String> headers)
    {
        if (Objects.nonNull(headers) && !headers.isEmpty())
        {
            for (Map.Entry<String, String> entry : headers.entrySet())
            {
                request.setHeader(entry.getKey(), entry.getValue());
            }
        } else
        {
            request.setHeader("Connection", "keep-alive");
            request.setHeader("Accept-Encoding", "gzip, deflate, br");
            request.setHeader("Accept", "*/*");
            request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");
        }
    }

    private static String getRespString(HttpUriRequest request, Map<String, String> headers)
    {
        byte[] bytes = new byte[BYTE_ARRAY_LENGTH];
        int len = 0;
        CloseableHttpResponse closeableHttpResponse = null;
        try
        {
            setHeaders(request, headers);
            closeableHttpResponse =  HttpClients.createDefault().execute(request);
            HttpEntity entity = closeableHttpResponse.getEntity();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            if (Objects.isNull(entity.getContent()))
            {
                return "";
            }
            while ((len = entity.getContent().read(bytes)) != -1)
            {
                bos.write(bytes, 0, len);
            }
            return bos.toString(UTF8);
        } catch (Exception e)
        {
            e.printStackTrace();
            return "";
        } finally
        {
            if (closeableHttpResponse != null)
            {
                try
                {
                    closeableHttpResponse.close();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
