package eu.dnetlib.data.utils;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import eu.dnetlib.data.mdstore.plugins.GenericDoiMdstorePlugin;

public class HttpFetcher {

	private static final Log log = LogFactory.getLog(GenericDoiMdstorePlugin.class);
	public static final int MAX_NUMBER_OF_ATTEMPTS = 3;
	private static final int INTERVAL_MILLIS = 20000;

	private static final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
	private static SSLConnectionSocketFactory sslSocketFactory;
	static {
		try {
			sslContextBuilder.loadTrustMaterial(null, (chain, authType) -> true);
			sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build());
		} catch (final NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
			log.error(e);;
		}
	}
	private static final HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder
			.create()
			.setConnectionTimeToLive(0, TimeUnit.MILLISECONDS)
			.setMaxConnPerRoute(1)
			.setMaxConnTotal(1)
			.disableAutomaticRetries()
			.disableConnectionState()
			.setSSLSocketFactory(sslSocketFactory)
			.build());

	public static String fetch(final String url) throws URISyntaxException {
		return fetch(new URI(url), 1);
	}

	public static String fetch(final URI url) {
		return fetch(url, 1);
	}

	public static String fetch(final URI url, final int attempts) {
		if (attempts > MAX_NUMBER_OF_ATTEMPTS) {
			log.error("Max number of attempts reached, downloading url: " + url);
			return "";
		}

		try {
			log.debug("Downloading URL: " + url + " - try: " + attempts);
			return (new RestTemplate(httpRequestFactory)).getForObject(url, String.class);
		} catch (final Throwable e) {
			try {
				log.error("Error downloading url: " + url + " - try: " + attempts + " - " + e.getMessage());
				Thread.sleep(INTERVAL_MILLIS);
				return fetch(url, attempts + 1);
			} catch (final InterruptedException e1) {
				log.error(e);
				return "";
			}
		}
	}
}
