package com.sptg.video.cloud.api.beans;

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.*;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.lang.reflect.Type;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

/**
 * @author zwx
 * @create 2020/10/17 19:04
 */
public class HttpsRestTemplate extends RestTemplate {

    public HttpsRestTemplate(){
        this(getHttpRequestFactory());
    }

    private static HttpComponentsClientHttpRequestFactory getHttpRequestFactory(){
        HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(createHttpClient());
//        httpComponentsClientHttpRequestFactory.setConnectTimeout(1000);
//        httpComponentsClientHttpRequestFactory.setConnectionRequestTimeout(1000);
        return httpComponentsClientHttpRequestFactory;
    }

    public HttpsRestTemplate(ClientHttpRequestFactory requestFactory, List<HttpMessageConverter<?>> messageConverters){
        setRequestFactory(requestFactory);
        setMessageConverters(messageConverters);
    }

    public HttpsRestTemplate(ClientHttpRequestFactory requestFactory){
        setRequestFactory(requestFactory);
        List<HttpMessageConverter<?>> mc = getMessageConverters();
        mc.add(new FormHttpMessageConverter());
        mc.add(new BufferedImageHttpMessageConverter());
        mc.add(new ByteArrayHttpMessageConverter());
        mc.add(new StringHttpMessageConverter());
        mc.add(new ResourceHttpMessageConverter());
    }

    public static CloseableHttpClient createHttpClient(){
        HttpClientBuilder b = HttpClientBuilder.create();
        SSLContext sslContext = null;
        try{
            sslContext = new SSLContextBuilder().loadTrustMaterial(null,new TrustStrategy(){
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }).build();
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
        b.setSSLContext(sslContext);
        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,hostnameVerifier);
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https",sslSocketFactory).build();
        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        connMgr.setMaxTotal(1000);
        connMgr.setDefaultMaxPerRoute(500);
        b.setConnectionManager(connMgr);
        CloseableHttpClient client = b.build();
        return client;
    }

}
