/*******************************************************************************
 * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
 * Technische Universitaet Muenchen.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Otto von Wesendonk - initial API and implementation
 ******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.connectionmanager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Enumeration;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
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.TrustManagerFactory;

import org.apache.commons.codec.binary.Base64;
import org.eclipse.emf.emfstore.client.exceptions.ESCertificateException;
import org.eclipse.emf.emfstore.client.provider.ESClientConfigurationProvider;
import org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionPoint;
import org.eclipse.emf.emfstore.internal.client.model.Configuration;
import org.eclipse.emf.emfstore.internal.client.model.ServerInfo;
import org.eclipse.emf.emfstore.internal.client.model.util.WorkspaceUtil;
import org.eclipse.emf.emfstore.internal.common.model.util.FileUtil;

/**
 * The KeyStoreManager manages the client's KeyStore in which the SSL
 * certificates for multiple EMFStore servers can be stored.
 *
 * @author wesendon
 */

public final class KeyStoreManager implements ESKeyStoreManager {

	private static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword"; //$NON-NLS-1$
	private static final String JAVAX_NET_SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword"; //$NON-NLS-1$
	private static final String JAVAX_NET_SSL_KEY_STORE = "javax.net.ssl.keyStore"; //$NON-NLS-1$
	private static final String JAVAX_NET_SSL_TRUST_STORE = "javax.net.ssl.trustStore"; //$NON-NLS-1$
	private static final String PROVIDER_CLASS = "providerClass"; //$NON-NLS-1$
	private static final String ORG_ECLIPSE_EMF_EMFSTORE_CLIENT_DEFAULT_CONFIGURATION_PROVIDER = "org.eclipse.emf.emfstore.client.defaultConfigurationProvider"; //$NON-NLS-1$
	/**
	 * Name of keyStore file.
	 */
	public static final String KEYSTORENAME = "emfstoreClient.keystore"; //$NON-NLS-1$
	private static final String KEYSTOREPASSWORD = "654321"; //$NON-NLS-1$
	private static final String CERTIFICATE_TYPE = "X.509"; //$NON-NLS-1$
	private static final String CIPHER_ALGORITHM = "RSA"; //$NON-NLS-1$

	/**
	 * Certificate Alias for development test certificate.
	 */
	public static final String DEFAULT_CERTIFICATE = "emfstore test certificate (do not use in production!)"; // "EMFStore Test Certificate (DO NOT USE IN PRODUCTION!)"; //$NON-NLS-1$

	private static KeyStoreManager instance;

	private String defaultCertificate;
	private KeyStore keyStore;

	private KeyStoreManager() {
		defaultCertificate = null;
		setupKeys();
		loadConfiguration();
	}

	private void loadConfiguration() {
		final ESClientConfigurationProvider provider = new ESExtensionPoint(
			ORG_ECLIPSE_EMF_EMFSTORE_CLIENT_DEFAULT_CONFIGURATION_PROVIDER).getClass(PROVIDER_CLASS,
			ESClientConfigurationProvider.class);
		if (provider == null) {
			return;
		}
		provider.initDefaultCertificates(this);

	}

	/**
	 * Returns an instance of the {@link KeyStoreManager}.
	 *
	 * @return {@link KeyStoreManager}
	 */
	public static synchronized KeyStoreManager getInstance() {
		if (instance == null) {
			instance = new KeyStoreManager();
		}
		return instance;
	}

	/**
	 * This method sets the JVM properties in order to use SSL encryption.
	 */
	public void setupKeys() {
		// No changes to exception handling here, due to call nature.
		if (!keyStoreExists()) {
			// create directory ~/.emfstore/ if necessary
			final File emfstoreDir = new File(Configuration.getFileInfo().getWorkspaceDirectory());
			if (!emfstoreDir.exists()) {
				emfstoreDir.mkdir();
			}
			final InputStream inputStream = getClass().getResourceAsStream(KEYSTORENAME);
			try {
				// configure file
				final File clientKeyTarget = new File(Configuration.getFileInfo().getWorkspaceDirectory()
					+ KEYSTORENAME);
				// copy to destination
				FileUtil.copyFile(inputStream, clientKeyTarget);
			} catch (final IOException e) {
				// TODO OW: exception? - now the user will be alerted to the
				// problem as soon as he tries to connect.
				// throw new ConnectionException("Couldn't find keystore.");
			} finally {
				try {
					inputStream.close();
				} catch (final IOException e) {
					// TODO: ignore exception for now, as above
				}
			}
		}

		System.setProperty(JAVAX_NET_SSL_TRUST_STORE, getPathToKeyStore());
		System.setProperty(JAVAX_NET_SSL_KEY_STORE, getPathToKeyStore());
		System.setProperty(JAVAX_NET_SSL_KEY_STORE_PASSWORD, KEYSTOREPASSWORD);
		System.setProperty(JAVAX_NET_SSL_TRUST_STORE_PASSWORD, KEYSTOREPASSWORD);
	}

	/**
	 * Lists all certificates in the client's KeyStore.
	 *
	 * @return string representation of the certificates
	 * @throws ESCertificateException
	 *             is thrown when problems occur with the CertificateStore, i.e.
	 *             illegal operations.
	 */
	public ArrayList<String> getCertificates() throws ESCertificateException {
		loadKeyStore();
		final ArrayList<String> certificates = new ArrayList<String>();
		try {
			final Enumeration<String> aliases = keyStore.aliases();
			for (; aliases.hasMoreElements();) {
				final String tmp = aliases.nextElement();
				certificates.add(tmp);
			}
		} catch (final KeyStoreException e) {
			final String message = Messages.KeyStoreManager_Loading_Certificate_Failed;
			WorkspaceUtil.logException(message, e);
			throw new ESCertificateException(message, e);
		}
		return certificates;
	}

	/**
	 * Deletes a certificate in the keystore.
	 *
	 * @param alias
	 *            alias of certificate
	 * @throws ESCertificateException
	 *             is thrown when problems occur with the CertificateStore, i.e.
	 *             illegal operations.
	 */
	public void deleteCertificate(String alias) throws ESCertificateException {
		if (isDefaultCertificate(alias)) {
			throw new ESCertificateException(Messages.KeyStoreManager_Cannot_Delete_Default_Certificate);
		}

		loadKeyStore();
		try {
			keyStore.deleteEntry(alias);
			storeKeyStore();
		} catch (final KeyStoreException e) {
			final String message = Messages.KeyStoreManager_Deleting_Certificate_Failed;
			WorkspaceUtil.logException(message, e);
			throw new ESCertificateException(message, e);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager#addCertificate(java.lang.String,
	 *      java.lang.String)
	 */
	public void addCertificate(String alias, String path) throws ESCertificateException {
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(path);
			addCertificate(alias, fileInputStream);
		} catch (final FileNotFoundException e) {
			final String message = Messages.KeyStoreManager_Storing_Certificate_Failed;
			WorkspaceUtil.logException(message, e);
			throw new ESCertificateException(message, e);
		} finally {
			if (fileInputStream != null) {
				try {
					fileInputStream.close();
				} catch (final IOException e) {
					final String message = "Storing certificate failed!"; //$NON-NLS-1$
					WorkspaceUtil.logException(message, e);
					throw new ESCertificateException(message, e);
				}
			}
		}
	}

	/**
	 * Remove certificate with the given alias.
	 *
	 * @param alias the certificate alias
	 * @throws ESCertificateException if removal fails
	 */
	public void removeCertificate(String alias) throws ESCertificateException {
		try {
			keyStore.deleteEntry(alias);
			storeKeyStore();
		} catch (final KeyStoreException e) {
			final String message = Messages.KeyStoreManager_Keystore_Not_Initialized;
			WorkspaceUtil.logException(message, e);
			throw new ESCertificateException(message, e);
		} catch (final ESCertificateException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logException(message, e);
			throw new ESCertificateException(message, e);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager#addCertificate(java.lang.String,
	 *      java.io.InputStream)
	 */
	public void addCertificate(String alias, InputStream certificate) throws ESCertificateException {
		if (!isDefaultCertificate(alias)) {
			loadKeyStore();
			try {
				final CertificateFactory factory = CertificateFactory.getInstance(CERTIFICATE_TYPE);
				final Certificate newCertificate = factory.generateCertificate(certificate);
				keyStore.setCertificateEntry(alias, newCertificate);
				storeKeyStore();
			} catch (final CertificateException e) {
				final String message = Messages.KeyStoreManager_Choose_Valid_Certificate;
				throw new ESCertificateException(message);
			} catch (final KeyStoreException e) {
				final String message = "Storing certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logException(message, e);
				throw new ESCertificateException(message, e);
			}
		}
	}

	private void storeKeyStore() throws ESCertificateException {
		loadKeyStore();
		try {
			final FileOutputStream fileOutputStream = new FileOutputStream(getPathToKeyStore());
			keyStore.store(fileOutputStream, KEYSTOREPASSWORD.toCharArray());
			fileOutputStream.close();
		} catch (final KeyStoreException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logWarning(message, e);
			throw new ESCertificateException(message, e);
		} catch (final NoSuchAlgorithmException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logWarning(message, e);
			throw new ESCertificateException(message, e);
		} catch (final CertificateException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logWarning(message, e);
			throw new ESCertificateException(message, e);
		} catch (final FileNotFoundException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logWarning(message, e);
			throw new ESCertificateException(message, e);
		} catch (final IOException e) {
			final String message = "Storing certificate failed!"; //$NON-NLS-1$
			WorkspaceUtil.logWarning(message, e);
			throw new ESCertificateException(message, e);
		}
	}

	/**
	 * Reloads the keystore.
	 *
	 * @throws ESCertificateException
	 *             in case of failure
	 */
	public void reloadKeyStore() throws ESCertificateException {
		keyStore = null;
		loadKeyStore();
	}

	private void loadKeyStore() throws ESCertificateException {
		if (keyStore == null) {
			try {
				keyStore = KeyStore.getInstance("JKS"); //$NON-NLS-1$
				final FileInputStream fileInputStream = new FileInputStream(getPathToKeyStore());
				keyStore.load(fileInputStream, KEYSTOREPASSWORD.toCharArray());
				fileInputStream.close();
			} catch (final KeyStoreException e) {
				final String message = "Loading certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logWarning(message, e);
				throw new ESCertificateException(message, e);
			} catch (final NoSuchAlgorithmException e) {
				final String message = "Loading certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logWarning(message, e);
				throw new ESCertificateException(message, e);
			} catch (final CertificateException e) {
				final String message = "Loading certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logWarning(message, e);
				throw new ESCertificateException(message, e);
			} catch (final FileNotFoundException e) {
				final String message = "Loading certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logWarning(message, e);
				throw new ESCertificateException(message, e);
			} catch (final IOException e) {
				final String message = "Loading certificate failed!"; //$NON-NLS-1$
				WorkspaceUtil.logWarning(message, e);
				throw new ESCertificateException(message, e);
			}
		}
	}

	/**
	 * Returns a SSL Context. This is need for encryption, used by the
	 * SSLSocketFactory.
	 *
	 * @return SSL Context
	 * @throws ESCertificateException
	 *             in case of failure retrieving the context
	 */
	public SSLContext getSSLContext() throws ESCertificateException {
		try {
			loadKeyStore();
			final KeyManagerFactory managerFactory = KeyManagerFactory.getInstance("SunX509"); //$NON-NLS-1$
			managerFactory.init(keyStore, KEYSTOREPASSWORD.toCharArray());
			final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); //$NON-NLS-1$
			trustManagerFactory.init(keyStore);
			final SSLContext sslContext = SSLContext.getInstance("TLS"); //$NON-NLS-1$
			sslContext.init(managerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
				public boolean verify(String hostname, SSLSession session) {
					return true;
				}
			});

			return sslContext;
		} catch (final NoSuchAlgorithmException e) {
			throw new ESCertificateException(Messages.KeyStoreManager_29, e);
		} catch (final UnrecoverableKeyException e) {
			throw new ESCertificateException("Loading certificate failed!", e); //$NON-NLS-1$
		} catch (final KeyStoreException e) {
			throw new ESCertificateException("Loading certificate failed!", e); //$NON-NLS-1$
		} catch (final KeyManagementException e) {
			throw new ESCertificateException("Loading certificate failed!", e); //$NON-NLS-1$
		}
	}

	/**
	 * True if a KeyStore file exists.
	 *
	 * @return boolean
	 */
	public boolean keyStoreExists() {
		final File keyStore = new File(getPathToKeyStore());
		return keyStore.exists();
	}

	/**
	 * Returns the path to the KeyStore.
	 *
	 * @return a path
	 */
	public String getPathToKeyStore() {
		return Configuration.getFileInfo().getWorkspaceDirectory() + KEYSTORENAME;
	}

	/**
	 * Encrypts a password.
	 *
	 * @param password
	 *            the password to be encrypted
	 * @param server
	 *            the server from which to fetch the public key that is used for encryption
	 * @return the encrypted password
	 */
	public String encrypt(String password, ServerInfo server) {
		try {
			final Certificate publicKey = getCertificateForEncryption(server);
			final PublicKey key = publicKey.getPublicKey();
			final byte[] inpBytes = password.getBytes();
			final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			final byte[] encryptededByteAr = cipher.doFinal(inpBytes);
			final byte[] base64EncodedByteAr = Base64.encodeBase64(encryptededByteAr);
			return new String(base64EncodedByteAr);
			// TODO: OW When new login proxy object with encryption handler is
			// implemented, handle exceptions
		} catch (final NoSuchAlgorithmException e) {
			// nothing to do
			e.printStackTrace();
		} catch (final NoSuchPaddingException e) {
			// nothing to do
			e.printStackTrace();
		} catch (final InvalidKeyException e) {
			// nothing to do
			e.printStackTrace();
		} catch (final IllegalBlockSizeException e) {
			// nothing to do
			e.printStackTrace();
		} catch (final BadPaddingException e) {
			// nothing to do
			e.printStackTrace();
		} catch (final ESCertificateException e) {
			// Auto-generated catch block
			e.printStackTrace();
		}
		WorkspaceUtil.logException(Messages.KeyStoreManager_Could_Not_Encrypt_Password, new ESCertificateException(
			Messages.KeyStoreManager_34));
		return ""; //$NON-NLS-1$
	}

	private Certificate getCertificateForEncryption(ServerInfo server) throws ESCertificateException {
		Certificate publicKey;
		if (server == null) {
			publicKey = getCertificate(getDefaultCertificate());
		} else {
			publicKey = getCertificate(server.getCertificateAlias());
		}
		if (publicKey == null) {
			publicKey = getCertificate(getDefaultCertificate());
			if (publicKey == null) {
				throw new ESCertificateException(Messages.KeyStoreManager_Unable_To_Get_Password);
			}
		}
		return publicKey;
	}

	/**
	 * Test whether a given alias is the default certificate alias.
	 *
	 * @param alias
	 *            alias under test
	 * @return true if default, false else
	 */
	public boolean isDefaultCertificate(String alias) {
		return getDefaultCertificate().equals(alias);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager#getDefaultCertificate()
	 */
	public String getDefaultCertificate() {
		if (defaultCertificate != null) {
			return defaultCertificate;
		} else if (Configuration.getVersioningInfo().isDeveloperVersion()) {
			return DEFAULT_CERTIFICATE;
		} else {
			return DEFAULT_CERTIFICATE;
		}
	}

	/**
	 * Returns true if the given alias maps to an existing certificate.
	 *
	 * @param alias
	 *            Certificate alias
	 * @return boolean
	 * @throws ESCertificateException
	 *             is thrown when problems occur with the CertificateStore, i.e.
	 *             illegal operations.
	 */
	public boolean contains(String alias) throws ESCertificateException {
		if (getCertificate(alias) == null) {
			return false;
		}
		return true;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager#setDefaultCertificate(java.lang.String)
	 */
	public void setDefaultCertificate(String defaultCertificate) {
		this.defaultCertificate = defaultCertificate;
	}

	/**
	 * Returns the certificate mapped by the given alias. Returns null if no
	 * such certificate exists.
	 *
	 * @param alias
	 *            String
	 * @return Certificate
	 * @throws ESCertificateException
	 *             is thrown when problems occur with the CertificateStore, i.e.
	 *             illegal operations.
	 */
	public Certificate getCertificate(String alias) throws ESCertificateException {
		if (alias == null) {
			return null;
		}
		loadKeyStore();
		try {
			return keyStore.getCertificate(alias);
		} catch (final KeyStoreException e) {
			throw new ESCertificateException("Loading certificate failed!"); //$NON-NLS-1$
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.client.provider.ESKeyStoreManager#certificateExists(java.lang.String)
	 */
	public boolean certificateExists(String alias) throws ESCertificateException {
		try {
			return getCertificate(alias) != null;
		} catch (final ESCertificateException e) {
			if (!(e.getCause() instanceof FileNotFoundException)) {
				throw e;
			}
		}
		return false;
	}
}