package com.vaguehope.onosendai.provider.successwhale;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParamBean;
import org.apache.http.params.HttpParams;

/**
 * https://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html
 * https:
 * //hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http
 * /impl/conn/tsccm/ThreadSafeClientConnManager.html
 */
public class HttpClientFactory {

	private static final int CONNECTION_TIMEOUT = 20000;
	private static final int SO_TIMEOUT = 30000;

	private static final String TS_PATH = "/successwhale.bks";
	private static final char[] TS_PASSWORD = "123456".toCharArray();

	private volatile HttpClient httpClient;

	public synchronized HttpClient getHttpClient () throws SuccessWhaleException {
		try {
			if (this.httpClient == null) this.httpClient = makeHttpClient();
			return this.httpClient;
		}
		catch (IOException e) {
			throw new SuccessWhaleException("Failed to create HTTP client: " + e.toString(), e);
		}
		catch (GeneralSecurityException e) {
			throw new SuccessWhaleException("Failed to create HTTP client. " + e.toString(), e);
		}
	}

	public synchronized void shutdown () {
		if (this.httpClient != null) this.httpClient.getConnectionManager().shutdown();
	}

	private static HttpClient makeHttpClient () throws IOException, GeneralSecurityException {
		HttpParams params = new BasicHttpParams();
		configureTimeouts(params, CONNECTION_TIMEOUT, SO_TIMEOUT);

		ClientConnectionManager conman = new ThreadSafeClientConnManager(params, new SchemeRegistry());
		addHttpSchema(conman);
		addHttpsSchemaForTrustStore(conman, TS_PATH, TS_PASSWORD);

		return new DefaultHttpClient(conman, params);
	}

	private static void configureTimeouts (final HttpParams params, final int connectionTimeout, final int soTimeout) {
		HttpConnectionParamBean connParam = new HttpConnectionParamBean(params);
		connParam.setConnectionTimeout(connectionTimeout);
		connParam.setSoTimeout(soTimeout);
	}

	private static void addHttpSchema (final ClientConnectionManager conman) {
		Scheme scheme = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); // NOSONAR 80 is not a magic number.  Its HTTP specification.
		conman.getSchemeRegistry().register(scheme);
	}

	private static void addHttpsSchemaForTrustStore (final ClientConnectionManager connMan, final String tsPath, final char[] password) throws IOException, GeneralSecurityException {
		KeyStore truststore = loadKeyStore(tsPath, password);
		SSLSocketFactory sf = new SSLSocketFactory(truststore);
		Scheme scheme = new Scheme("https", sf, 443); // NOSONAR 443 is not a magic number.  Its HTTPS specification.
		connMan.getSchemeRegistry().register(scheme);
	}

	private static KeyStore loadKeyStore (final String tsPath, final char[] password) throws IOException, GeneralSecurityException {
		KeyStore ks = KeyStore.getInstance("BKS");
		InputStream is = HttpClientFactory.class.getResourceAsStream(tsPath);
		try {
			ks.load(is, password);
		}
		finally {
			is.close();
		}
		return ks;
	}

}

@@ -283,63 +283,8 @@
 er;%0A
-import org.apache.http.conn.scheme.PlainSocketFactory;%0A
 impo
@@ -1416,16 +1416,22 @@
 %09catch (
+final 
 IOExcept
@@ -1540,16 +1540,22 @@
 %09catch (
+final 
 GeneralS
@@ -1888,24 +1888,30 @@
 ception %7B%0A%09%09
+final 
 HttpParams p
@@ -2005,16 +2005,22 @@
 UT);%0A%0A%09%09
+final 
 ClientCo
@@ -2111,33 +2111,8 @@
 ));%0A
-%09%09addHttpSchema(conman);%0A
 %09%09ad
@@ -2340,16 +2340,22 @@
 ut) %7B%0A%09%09
+final 
 HttpConn
@@ -2517,278 +2517,8 @@
 %09%7D%0A%0A
-%09private static void addHttpSchema (final ClientConnectionManager conman) %7B%0A%09%09Scheme scheme = new Scheme(%22http%22, PlainSocketFactory.getSocketFactory(), 80); // NOSONAR 80 is not a magic number.  Its HTTP specification.%0A%09%09conman.getSchemeRegistry().register(scheme);%0A%09%7D%0A%0A
 %09pri
@@ -2687,32 +2687,38 @@
 tyException %7B%0A%09%09
+final 
 KeyStore trustst
@@ -2757,16 +2757,22 @@
 ord);%0A%09%09
+final 
 SSLSocke
@@ -2821,16 +2821,22 @@
 ore);%0A%09%09
+final 
 Scheme s
@@ -3121,16 +3121,22 @@
 ion %7B%0A%09%09
+final 
 KeyStore
@@ -3172,16 +3172,22 @@
 KS%22);%0A%09%09
+final 
 InputStr
@@ -3282,16 +3282,30 @@
 sword);%0A
+%09%09%09return ks;%0A
 %09%09%7D%0A%09%09fi
@@ -3331,27 +3331,14 @@
 ();%0A%09%09%7D%0A
-%09%09return ks;%0A
 %09%7D%0A%0A%7D%0A

Remove unused HTTP client config.