package lu.tudor.santec.gecamed.esante.gui.webservice;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SSLManager {

	private static SSLSocketFactory factory = null;
	static boolean initialized = false;
	private static KeyStore keystore = null;
	private static KeyManagerFactory kmf = null;

	/**
	 * Prepares the SSL Manager for a new initialization (e.g. with a new keystore). A subsequent call to initSSL will reinitialize the key manager with the new
	 * data
	 */
	public static void reset() {
		initialized = false;
	}
	
	public static SSLSocketFactory initSSL(String keystorePath, String keystorePassword) {

		if (initialized)
			return factory;

		try {
			// load the keystore from file
			SSLManager.keystore = KeyStore.getInstance("JKS");
			SSLManager.keystore.load(new FileInputStream(new File(keystorePath)), keystorePassword.toCharArray());

			// and create a key manager factory
			SSLManager.kmf = KeyManagerFactory.getInstance("SunX509");
			SSLManager.kmf.init(SSLManager.keystore, keystorePassword.toCharArray());

			// create an ssl context
			SSLContext sslContext = SSLContext.getInstance("TLS");

			// and initialize it with the keystore (for client authentication) and a TrustManager that trusts everything (meaning any server will be trusted -
			// SECURITY RISK - SHOULD NOT BE USED IN PRODUCTION ENVIRONMENT!)
			sslContext.init(SSLManager.kmf.getKeyManagers(), new TrustManager[] { new X509TrustManager() {
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}

				public void checkClientTrusted(X509Certificate[] certs, String authType) {
					// everything is trusted
				}

				public void checkServerTrusted(X509Certificate[] certs, String authType) {
					// everything is trusted
				}
			} }, new SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

			// setup a hostname verifier that verifies everything
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
				public boolean verify(String arg0, SSLSession arg1) {
					return true;
				}
			});
			
			SSLManager.factory = sslContext.getSocketFactory();
			// this procedure does not have to be passed a 2nd time
			initialized = true;
			
		} catch (Exception e) {
			e.printStackTrace();
		}

		return factory;
	}
}
