/*******************************************************************************
 * Copyright (c) 2008, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.security.storage;

import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.equinox.internal.security.auth.AuthPlugin;
import org.eclipse.equinox.internal.security.auth.nls.SecAuthMessages;
import org.eclipse.equinox.internal.security.storage.friends.IStorageConstants;
import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.equinox.security.storage.provider.PasswordProvider;
import org.eclipse.osgi.util.NLS;

//XXX add validation on module IDs - AZaz09 and dots, absolutely no tabs 
// XXX reserved name DEFAULT_PASSWORD_ID

/**
 * Finds appropriate password provider module to use.
 */
public class PasswordProviderSelector implements IRegistryEventListener {

	final private static String EXTENSION_POINT = "org.eclipse.equinox.security.secureStorage"; //$NON-NLS-1$
	final private static String STORAGE_MODULE = "provider";//$NON-NLS-1$
	final private static String MODULE_PRIORITY = "priority";//$NON-NLS-1$
	final private static String MODULE_DESCRIPTION = "description";//$NON-NLS-1$
	final private static String CLASS_NAME = "class";//$NON-NLS-1$
	final private static String HINTS_NAME = "hint";//$NON-NLS-1$
	final private static String HINT_VALUE = "value";//$NON-NLS-1$

	private Map modules = new HashMap(5); // cache of modules found

	public class ExtStorageModule {
		public String moduleID;
		public IConfigurationElement element;
		public int priority;
		public String name;
		public String description;
		public List hints;

		public ExtStorageModule(String id, IConfigurationElement element, int priority, String name, String description, List hints) {
			super();
			this.element = element;
			this.moduleID = id;
			this.priority = priority;
			this.name = name;
			this.description = description;
			this.hints = hints;
		}
	}

	static private PasswordProviderSelector instance = null;

	static public PasswordProviderSelector getInstance() {
		if (instance == null) {
			instance = new PasswordProviderSelector();
			IExtensionRegistry registry = RegistryFactory.getRegistry();
			registry.addListener(instance, EXTENSION_POINT);
		}
		return instance;
	}

	static public void stop() {
		if (instance != null) {
			IExtensionRegistry registry = RegistryFactory.getRegistry();
			registry.removeListener(instance);
			instance = null;
		}
	}

	private PasswordProviderSelector() {
		// hides default constructor; use getInstance()
	}

	public List findAvailableModules(String expectedID) {

		IExtensionRegistry registry = RegistryFactory.getRegistry();
		IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT);
		IExtension[] extensions = point.getExtensions();

		ArrayList allAvailableModules = new ArrayList(extensions.length);

		for (int i = 0; i < extensions.length; i++) {
			String moduleID = extensions[i].getUniqueIdentifier();
			if (moduleID == null) // IDs on those extensions are mandatory; if not specified, ignore the extension
				continue;
			moduleID = moduleID.toLowerCase();
			if (expectedID != null && !expectedID.equals(moduleID))
				continue;
			IConfigurationElement[] elements = extensions[i].getConfigurationElements();
			if (elements.length == 0)
				continue;
			IConfigurationElement element = elements[0]; // only one module is allowed per extension
			if (!STORAGE_MODULE.equals(element.getName())) {
				reportError(SecAuthMessages.unexpectedConfigElement, element.getName(), element, null);
				continue;
			}
			String attribute = element.getAttribute(MODULE_PRIORITY);
			int priority = -1;
			if (attribute != null) {
				priority = Integer.parseInt(attribute);
				if (priority < 0)
					priority = 0;
				if (priority > 10)
					priority = 10;
			}
			String name = extensions[i].getLabel();

			String description = element.getAttribute(MODULE_DESCRIPTION);

			List suppliedHints = null;
			IConfigurationElement[] hints = element.getChildren(HINTS_NAME);
			if (hints.length != 0) {
				suppliedHints = new ArrayList(hints.length);
				for (int j = 0; j < hints.length; j++) {
					String hint = hints[j].getAttribute(HINT_VALUE);
					if (hint != null)
						suppliedHints.add(hint);
				}
			}

			allAvailableModules.add(new ExtStorageModule(moduleID, element, priority, name, description, suppliedHints));
		}

		Collections.sort(allAvailableModules, new Comparator() {
			public int compare(Object o1, Object o2) {
				int p1 = ((ExtStorageModule) o1).priority;
				int p2 = ((ExtStorageModule) o2).priority;
				return p2 - p1;
			}
		});

		return allAvailableModules;
	}

	public PasswordProviderModuleExt findStorageModule(String expectedID) throws StorageException {
		if (expectedID != null)
			expectedID = expectedID.toLowerCase(); // ID is case-insensitive
		synchronized (modules) {
			if (modules.containsKey(expectedID))
				return (PasswordProviderModuleExt) modules.get(expectedID);
		}

		List allAvailableModules = findAvailableModules(expectedID);
		HashSet disabledModules = getDisabledModules();

		for (Iterator i = allAvailableModules.iterator(); i.hasNext();) {
			ExtStorageModule module = (ExtStorageModule) i.next();

			if (expectedID == null && disabledModules != null && disabledModules.contains(module.moduleID))
				continue;

			Object clazz;
			try {
				clazz = module.element.createExecutableExtension(CLASS_NAME);
			} catch (CoreException e) {
				reportError(SecAuthMessages.instantiationFailed, module.element.getAttribute(CLASS_NAME), module.element, e);
				continue;
			}
			if (!(clazz instanceof PasswordProvider))
				continue;

			PasswordProviderModuleExt result = new PasswordProviderModuleExt((PasswordProvider) clazz, module.moduleID);

			// cache the result
			synchronized (modules) {
				if (expectedID == null)
					modules.put(null, result);
				modules.put(module.moduleID, result);
			}

			return result;
		}

		// the secure storage module was not found - error in app's configuration
		String msg;
		if (expectedID == null)
			msg = SecAuthMessages.noSecureStorageModules;
		else
			msg = NLS.bind(SecAuthMessages.noSecureStorageModule, expectedID);
		throw new StorageException(StorageException.NO_SECURE_MODULE, msg);
	}

	private void reportError(String template, String arg, IConfigurationElement element, Throwable e) {
		String supplier = element.getContributor().getName();
		String message = NLS.bind(template, arg, supplier);
		AuthPlugin.getDefault().logError(message, e);
	}

	//////////////////////////////////////////////////////////////////////////////////////////////
	// Synch local cache with the registry 
	public void added(IExtension[] extensions) {
		clearCaches();
	}

	public void added(IExtensionPoint[] extensionPoints) {
		clearCaches();
	}

	public void removed(IExtension[] extensions) {
		clearCaches();
	}

	public void removed(IExtensionPoint[] extensionPoints) {
		clearCaches();
	}

	/**
	 * Clear whole cache as priorities might have changed after new modules were added.
	 */
	public void clearCaches() {
		synchronized (modules) {
			modules.clear();
			// If module was removed, clear its entry from the password cache.
			// The code below clears all entries for simplicity, in future this
			// can be made more limiting if a scenario exists where module
			// removal/addition is a frequent event.
			SecurePreferencesMapper.clearPasswordCache();
		}
	}

	public boolean isLoggedIn() {
		synchronized (modules) {
			return (modules.size() != 0);
		}
	}

	protected HashSet getDisabledModules() {
		IEclipsePreferences node = ConfigurationScope.INSTANCE.getNode(AuthPlugin.PI_AUTH);
		String tmp = node.get(IStorageConstants.DISABLED_PROVIDERS_KEY, null);
		if (tmp == null || tmp.length() == 0)
			return null;
		HashSet disabledModules = new HashSet();
		String[] disabledProviders = tmp.split(","); //$NON-NLS-1$
		for (int i = 0; i < disabledProviders.length; i++) {
			disabledModules.add(disabledProviders[i]);
		}
		return disabledModules;
	}
}
