package cn.superdesk.uniorder.common;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

/**
 * @author xc
 * @description 这个工具类是用来推送账单状态到集采的，有重试机制，使用时避免非幂等请求重试。
 * @date 2022/4/10 18:02
 */
public class HttpUtil {
    private final static PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

    static {
        manager.setMaxTotal(100);
        manager.setDefaultMaxPerRoute(10);
    }

    private static RequestConfig getRequestConfig() {
        return RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(60000).setConnectionRequestTimeout(60000).build();
    }

    public static String post(String postData, String postUrl) {

        String result = "";
        try {
            CloseableHttpClient httpClient = getHttpClient();
            HttpPost post = new HttpPost(postUrl);
            post.setConfig(getRequestConfig());
            StringEntity postingString = new StringEntity(postData, "UTF-8");
            post.setEntity(postingString);
            post.setHeader("Content-type", "application/json");
            HttpResponse response = httpClient.execute(post);
            result = EntityUtils.toString(response.getEntity());
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
            result = e.getMessage();
        }
        return result;
    }

    /**
     * 获取httpClient,默认重试3次
     * @return
     */
    public static CloseableHttpClient getHttpClient() {
        HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {

            @Override
            public boolean retryRequest(IOException e, int retryTime, HttpContext httpContext) {
                if (retryTime > 2) {
                    //重试超过2次，就放弃
                    return false;
                }
                if (e instanceof InterruptedIOException) {
                    return false;
                }
                if ( e instanceof UnknownHostException) {
                    return false;
                }
                if ( e instanceof SSLException) {
                    return false;
                }
                /**
                 * 需要根据请求是否幂等决定是否重试，这里未做判断，是因为只是推送账单的状态到集采，这个操作是幂等的
                 * 但是因为集采那边统一POST一把梭，这里判断无意义
                 *
                 * request instanceof HttpEntityEnclosingRequest
                 */
                return true;
            }
        };

        return HttpClients.custom().setRetryHandler(handler).build();
    }
}
