package eu.dnetlib.data.collector.plugins;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLProtocolException;

import com.google.common.base.Joiner;
import eu.dnetlib.data.collector.rmi.CollectorServiceException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@Ignore
public class HttpConnectorTest {

	private static final Log log = LogFactory.getLog(HttpConnectorTest.class);
	private HttpConnector connector;

	private static final String URL = "https://researchdata.ands.org.au/registry/services/oai?verb=Identify";
	private static final String URL_MISCONFIGURED_SERVER = "https://www.alexandria.unisg.ch/cgi/oai2?verb=Identify";
	private static final String URL_GOODSNI_SERVER = "https://air.unimi.it/oai/openaire?verb=Identify";

	private static final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
	private static SSLConnectionSocketFactory sslSocketFactory;

	private static final HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder
			.create()
			.setConnectionTimeToLive(0, TimeUnit.MILLISECONDS)
			.setMaxConnPerRoute(1)
			.setMaxConnTotal(1)
			.disableAutomaticRetries()
			.disableConnectionState()
			.setSSLSocketFactory(sslSocketFactory)
			.build());

//	static {
//		System.setProperty("javax.net.debug", "ssl,handshake");
//		System.setProperty("jsse.enableSNIExtension", "true");
//		try {
//			sslContextBuilder.loadTrustMaterial(null, (chain, authType) -> true);
//			SSLParameters sslParameters = new SSLParameters();
//			List sniHostNames = new ArrayList(1);
//			//sniHostNames.add(new SNIHostName(url.getHost()));
//			sslParameters.setServerNames(sniHostNames);
//			sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build().se, sslParameters);
//
//		} catch (final NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
//			log.error(e);;
//		}
//	}

	@Before
	public void setUp() {
		connector = new HttpConnector();
	}

	@Test
	@Ignore
	public void testConnectionRelease() throws IOException, InterruptedException {

		InputStream in;

		final HttpGet get = new HttpGet("http://www.google.com");
		try(CloseableHttpResponse rsp = HttpClients.createDefault().execute(get)) {

			in = rsp.getEntity().getContent();
		}

		log.info("going to sleep ... ");
		Thread.sleep(1000);

		log.info("wake up!");

		System.out.println(IOUtils.toString(in));
	}

	@Test
	@Ignore
	public void testGetInputSource() throws CollectorServiceException {
		System.out.println(connector.getInputSource(URL));
	}

	@Test
	@Ignore
	public void testMisconfiguredServers() throws CollectorServiceException {
		System.out.println(connector.getInputSource(URL_MISCONFIGURED_SERVER));
	}

	@Test
	@Ignore
	public void testMisconfiguredServers2() throws IOException {
		HttpURLConnection urlConn = (HttpURLConnection) new URL(URL_MISCONFIGURED_SERVER).openConnection();
		urlConn.getResponseMessage();
	}

	@Test
	public void testDisablingSNI() throws IOException {
		HttpURLConnection urlConn = null;
		try {
			urlConn = (HttpURLConnection) new URL(URL_MISCONFIGURED_SERVER).openConnection();
			urlConn.getResponseMessage();
		 } catch(SSLProtocolException sslExce) {
			if (sslExce.getMessage() != null && sslExce.getMessage().equals("handshake alert:  unrecognized_name")) {
				System.out.println("Server has misconfigured SSL SNI (handshake alert:  unrecognized_name). Trying to disable SNI");
				if (urlConn instanceof HttpsURLConnection) {
					HttpResponse res = httpRequestFactory.getHttpClient().execute(new HttpGet(URL_MISCONFIGURED_SERVER));
					System.out.println(res.getStatusLine());
//					HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConn;
//					httpsUrlConnection.setSSLSocketFactory(sslSocketFactory);
//					httpsUrlConnection.setHostnameVerifier(new HostnameVerifier() {
//						public boolean verify( String s, SSLSession sess ) {
//							return true;
//						}});
//					httpsUrlConnection.getResponseMessage();
				}

			}
		}
	}




	@Test
	public void testGoodServers() throws CollectorServiceException {
		System.out.println(connector.getInputSource(URL_GOODSNI_SERVER));
	}


}
