package com.tzld.piaoquan.growth.common.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * http util
 *
 * @author xueyiming
 */
public class HttpClientUtil {

    private static final String DEFAULT_SHARED_KEY = "DEFAULT_SHARED_KEY";

    /**
     * 链接建立的超时时间 ms
     */
    private static final int DEFAULT_CONNECTION_TIMEOUT = 3000;
    /**
     * 响应超时时间 ms
     */
    private static final int DEFAULT_SOCKET_TIMEOUT = 3000;

    /**
     * 每个路由的最大连接数
     */
    private static final int DEFAULT_DEFAULT_MAX_PER_ROUTE = 50;

    /**
     * 最大连接数
     */
    private static final int DEFAULT_DEFAULT_MAX_TOTAL = 200;

    /**
     * 重试次数，默认0
     */
    private static final int DEFAULT_RETRY_COUNT = 5;

    /**
     * 从connection pool中获得一个connection的超时时间 ms
     */
    private static final int DEFAULT_CONNECTION_WAIT_TIMEOUT = 300;

    private static final Map<String, HttpPoolClientUtil> CREATED_HTTP_CLIENTS = new HashMap<>();

    private static final Lock LOCK = new ReentrantLock();

    private HttpClientUtil() {
    }

    public static HttpPoolClientUtil useDefault() {
        return createCached(DEFAULT_SHARED_KEY);
    }


    public static HttpPoolClientUtil createCached(String cachedKey) {
        HttpPoolClientUtil httpPoolClientUtil = CREATED_HTTP_CLIENTS.get(cachedKey);
        if (httpPoolClientUtil != null) {
            return httpPoolClientUtil;
        }
        LOCK.lock();
        try {
            httpPoolClientUtil = CREATED_HTTP_CLIENTS.get(cachedKey);
            if (httpPoolClientUtil == null) {
                httpPoolClientUtil = create(DEFAULT_CONNECTION_TIMEOUT, DEFAULT_SOCKET_TIMEOUT, DEFAULT_DEFAULT_MAX_PER_ROUTE, DEFAULT_DEFAULT_MAX_TOTAL, DEFAULT_RETRY_COUNT, DEFAULT_CONNECTION_WAIT_TIMEOUT);
                CREATED_HTTP_CLIENTS.put(cachedKey, httpPoolClientUtil);
            }
        } finally {
            LOCK.unlock();
        }
        return httpPoolClientUtil;
    }

    /**
     * 创建httpclient
     *
     * @param connectTimeout        连接超时时间 ms
     * @param socketTimeout         读超时时间（等待数据超时时间）ms
     * @param maxPerRoute           每个路由的最大连接数
     * @param maxTotal              最大连接数
     * @param retryCount            重试次数
     * @param connectionWaitTimeout 连接等待超市时间 ms
     * @return httpclient instance
     */
    public static HttpPoolClientUtil create(int connectTimeout, int socketTimeout, int maxPerRoute, int maxTotal, int retryCount, int connectionWaitTimeout) {
        return HttpPoolClientUtil.create(connectTimeout, socketTimeout, maxPerRoute, maxTotal, retryCount, connectionWaitTimeout);
    }
}