package org.code.pomelo.thirdlib.httpclient.example;

import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.routing.HttpRoutePlanner;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
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.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

/**
 * Created by ruyin on 2018/6/25.
 *
 * Connection sockets factories
 *
 * PlainConnectionSocketFactory是创建初始化(未加密)的socket的默认工厂
 * LayeredConnectionSocketFactory
 */
public class ConnectionSocketFactoryDemo {

    public void buidPlainSf() throws IOException {
        HttpClientContext clientContext = HttpClientContext.create();
        //PlainConnectionSocketFactory.INSTANCE;
        PlainConnectionSocketFactory sf = PlainConnectionSocketFactory.getSocketFactory();
        Socket socket = sf.createSocket(clientContext);
        int timeout = 1000;
        HttpHost target = new HttpHost("localhost");
        InetSocketAddress remoteAddress = new InetSocketAddress(InetAddress.getByAddress(new byte[]{127,0,0,1}),80);
        sf.connectSocket(timeout,socket,target,remoteAddress,null,clientContext);
    }

    /**
     *
     * 2、Integration with connection manager
     *
     * */
    public void buidConnectionManager(){
        ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
        LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http",plainsf)
                .register("https",sslsf)
                .build();

        HttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        HttpClient client = HttpClients.custom()
                .setConnectionManager(cm)
                .build();
    }

    /**
     *
     * SSL/TLS customization
     *
     * */
    public void buidSSLCustomization() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        KeyStore myTrustStore = null;
        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(myTrustStore,null)
                .build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    }

    /**
     *
     * HttpClient proxy configuration
     *
     * */
    public void buidHttpClientProxy(){
        //1、default proxy parameter
        HttpHost proxy = new HttpHost("localhost",80);
        DefaultProxyRoutePlanner routePlanner1 = new DefaultProxyRoutePlanner(proxy);
        CloseableHttpClient httpClient1 = HttpClients
                .custom()
                .setRoutePlanner(routePlanner1)
                .build();

        //2、standard jre proxy selector
        SystemDefaultRoutePlanner routePlanner2 = new SystemDefaultRoutePlanner(ProxySelector.getDefault());
        CloseableHttpClient httpClient2 = HttpClients
                .custom()
                .setRoutePlanner(routePlanner2)
                .build();

        //3、provide a custom RoutePlanner
        HttpRoutePlanner routePlanner3 = (target, request, context) ->
                new HttpRoute(target,null,new HttpHost("localhost",8080),
                    "https".equalsIgnoreCase(target.getSchemeName()));
        CloseableHttpClient httpClient3 = HttpClients
                .custom()
                .setRoutePlanner(routePlanner3)
                .build();
    }


}
