/*******************************************************************************
 * Copyright (c) 2010 The Eclipse Foundation and others.
 * 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:
 *     The Eclipse Foundation - initial API and implementation
 *******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
import org.eclipse.epp.mpc.core.service.IMarketplaceStorageService;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.osgi.util.NLS;
import org.eclipse.userstorage.IBlob;
import org.eclipse.userstorage.IStorage;
import org.eclipse.userstorage.IStorageService;
import org.eclipse.userstorage.StorageFactory;
import org.eclipse.userstorage.internal.StorageService;
import org.eclipse.userstorage.oauth.EclipseOAuthCredentialsProvider;
import org.eclipse.userstorage.spi.Credentials;
import org.eclipse.userstorage.spi.ICredentialsProvider;
import org.eclipse.userstorage.spi.ISettings;
import org.eclipse.userstorage.util.FileStorageCache;
import org.eclipse.userstorage.util.Settings;
import org.osgi.framework.BundleContext;

@SuppressWarnings("restriction")
public class MarketplaceStorageService implements IMarketplaceStorageService {

	private static final String DEFAULT_STORAGE_SERVICE_NAME = Messages.MarketplaceStorageService_defaultStorageServiceName;

	static final String DEFAULT_APPLICATION_TOKEN = "MZ04RMOpksKN5GpxKXafq2MSjSP"; //$NON-NLS-1$

	private static final String[] MIGRATE_SECURE_STORAGE_KEYS = { "username", "password", "termsOfUseAgreed" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$

	private String applicationToken = DEFAULT_APPLICATION_TOKEN;

	private URI serviceUri;

	private StorageFactory storageFactory;

	private IStorage storage;

	private IStorageService.Dynamic customStorageService;

	private List<LoginListener> loginListeners;

	private EclipseOAuthCredentialsProvider credentialsProvider;

	private StorageConfigurer configurer;

	public URI getServiceUri() {
		return serviceUri;
	}

	public synchronized void setServiceUri(URI serviceUri) {
		if ((this.serviceUri == null && serviceUri != null)
				|| (this.serviceUri != null && !this.serviceUri.equals(serviceUri))) {
			this.serviceUri = serviceUri;
			storageFactory = null;
			storage = null;
		}
	}

	public synchronized StorageFactory getStorageFactory() {
		if (storageFactory == null) {
			storageFactory = createStorageFactory();
		}
		return storageFactory;
	}

	public synchronized void setStorageFactory(StorageFactory storageFactory) {
		this.storageFactory = storageFactory;
	}

	protected StorageFactory createStorageFactory() {
		if (serviceUri == null) {
			return StorageFactory.DEFAULT;
		}
		Map<String, String> settingsMap = new HashMap<String, String>();
		settingsMap.put(applicationToken, serviceUri.toString());
		ISettings storageFactorySettings = new Settings.MemorySettings(settingsMap);
		return new StorageFactory(storageFactorySettings);
	}

	protected IStorage createStorage() {
		IStorage storage = getStorageFactory().create(applicationToken,
				new FileStorageCache.SingleApplication(this.applicationToken));
		try {
			configurer = StorageConfigurer.get();
			configurer.configure(storage);
			configurer.setInteractive(storage, false);
		} catch (CoreException e) {
			configurer = null;
			MarketplaceClientCore.error(e);
		}
		return storage;
	}

	public synchronized IStorage getStorage() {
		if (storage == null) {
			storage = createStorage();
		}
		return storage;
	}

	public void setStorage(IStorage storage) {
		this.storage = storage;
	}

	public IBlob getBlob(String key) {
		return getStorage().getBlob(key);
	}

	public String getRegisteredUser() {
		Credentials credentials = getStorageCredentials();
		return credentials == null ? null : credentials.getUsername();
	}

	public <T> T runWithLogin(Callable<T> c) throws Exception {
		String oldUser = getCurrentUser();
		try {
			T result = configurer != null ? configurer.runWithLogin(storage, c) : c.call();
			return result;
		} finally {
			String newUser = getCurrentUser();//TODO the OAuth token might change with the user staying the same - this would cause an unnecessary refresh event
			notifyLoginChanged(oldUser, newUser);
		}
	}

	private void notifyLoginChanged(String oldUser, String newUser) {
		if ((newUser == null && oldUser != null) || (newUser != null && !newUser.equals(oldUser))) {
			List<LoginListener> loginListeners = this.loginListeners;
			if (loginListeners != null && !loginListeners.isEmpty()) {
				for (LoginListener loginListener : loginListeners) {
					loginListener.loginChanged(oldUser, newUser);
				}
			}
		}
	}

	public synchronized void addLoginListener(LoginListener listener) {
		if (loginListeners == null) {
			loginListeners = new CopyOnWriteArrayList<LoginListener>();
		}
		if (!loginListeners.contains(listener)) {
			loginListeners.add(listener);
		}
	}

	public synchronized void removeLoginListener(LoginListener listener) {
		if (loginListeners != null) {
			loginListeners.remove(listener);
		}
	}

	private String getCurrentUser() {
		Credentials credentials = getStorageCredentials();
		if (credentials != null && credentials.getPassword() != null) {
			return credentials.getUsername();
		}
		return null;
	}

	private Credentials getStorageCredentials() {
		ICredentialsProvider provider = getStorage().getCredentialsProvider();
		if (provider == null) {
			return null;
		}
		IStorageService service = getStorage().getService();
		//return provider.hasCredentials(service) ? provider.getCredentials(service) : null;
		return ((StorageService) service).getCredentials();
	}

	public void activate(BundleContext context, Map<?, ?> properties) {
		Object serviceUrlValue = ServiceUtil.getOverridablePropertyValue(properties, STORAGE_SERVICE_URL_PROPERTY);
		if (serviceUrlValue != null) {
			URI serviceUri = URI.create(serviceUrlValue.toString());
			String serviceName = getProperty(properties, STORAGE_SERVICE_NAME_PROPERTY, DEFAULT_STORAGE_SERVICE_NAME);
			IStorageService registered = registerStorageService(serviceUri, serviceName);
			setServiceUri(registered.getServiceURI());
		}
		String applicationToken = getProperty(properties, APPLICATION_TOKEN_PROPERTY, DEFAULT_APPLICATION_TOKEN);
		this.applicationToken = applicationToken;
	}

	private IStorageService registerStorageService(URI serviceUri, String serviceName) {
		customStorageService = null;
		URI normalizedUri = normalizePath(serviceUri);
		URI denormalizedUri = normalizePath(serviceUri, false);
		IStorageService service = IStorageService.Registry.INSTANCE.getService(normalizedUri);
		IStorageService extraService = IStorageService.Registry.INSTANCE.getService(denormalizedUri);
		if (service == null) {
			if (extraService != null) {
				return extraService;
			}
			customStorageService = IStorageService.Registry.INSTANCE.addService(serviceName, normalizedUri);
			service = customStorageService;
			return service;
		}
		if (extraService != null && extraService != service) {
			service = cleanupExtraStorageService(service, extraService);
		}

		return service;
	}

	private static IStorageService cleanupExtraStorageService(IStorageService service, IStorageService extraService) {
		IStorageService.Dynamic removeDynamic;
		IStorageService keepService;
		if (extraService instanceof IStorageService.Dynamic) {
			removeDynamic = (IStorageService.Dynamic) extraService;
			keepService = service;
		} else if (service instanceof IStorageService.Dynamic) {
			removeDynamic = (IStorageService.Dynamic) service;
			keepService = extraService;
		} else {
			return service;
		}
		if (removeDynamic instanceof StorageService && keepService instanceof StorageService) {
			StorageService removeImpl = (StorageService) removeDynamic;
			StorageService keepImpl = (StorageService) keepService;
			ISecurePreferences removeSecurePreferences = removeImpl.getSecurePreferences();
			ISecurePreferences keepSecurePreferences = keepImpl.getSecurePreferences();
			try {
				copySecurePreferences(removeSecurePreferences, keepSecurePreferences);
			} catch (Exception e) {
				MarketplaceClientCore.error(NLS.bind("Failed to migrate secure storage values from {0} to {1}",
						removeDynamic.getServiceURI(), keepService.getServiceURI()), e);
			}
		}
		removeDynamic.remove();
		return keepService;
	}

	private static void copySecurePreferences(ISecurePreferences source, ISecurePreferences target)
			throws StorageException, IOException {
		Set<String> sourceKeys = new HashSet<String>(Arrays.asList(source.keys()));
		Set<String> targetKeys = new HashSet<String>(Arrays.asList(target.keys()));
		boolean changed = false;
		for (String key : MIGRATE_SECURE_STORAGE_KEYS) {
			if (sourceKeys.contains(key) && !targetKeys.contains(key)) {
				boolean encrypted = source.isEncrypted(key);
				target.put(key, source.get(key, null), encrypted);
				changed = true;
			}
		}
		if (changed) {
			target.flush();
		}
	}

	private static URI normalizePath(URI uri) {
		return normalizePath(uri, true);
	}

	private static URI normalizePath(URI uri, boolean trailingSlash) {
		if (uri.isOpaque()) {
			return uri;
		}
		String path = uri.getPath();
		String normalizedPath;
		if (path == null) {
			if (trailingSlash) {
				normalizedPath = "/"; //$NON-NLS-1$
			} else {
				return uri;
			}
		} else if (path.endsWith("/")) { //$NON-NLS-1$
			if (trailingSlash) {
				return uri;
			} else {
				normalizedPath = path.length() == 1 ? null : path.substring(0, path.length() - 1);
			}
		} else {
			if (trailingSlash) {
				normalizedPath = path + "/"; //$NON-NLS-1$
			} else {
				return uri;
			}
		}
		try {
			return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), normalizedPath,
					uri.getQuery(), uri.getFragment());
		} catch (URISyntaxException e) {
			return uri;
		}
	}

	private static String getProperty(Map<?, ?> properties, String key, String defaultValue) {
		Object value = properties.get(key);
		if (value == null) {
			return defaultValue;
		}
		return value.toString();
	}

	public void deactivate() {
		if (customStorageService != null) {
			customStorageService.remove();
		}
		customStorageService = null;
	}
}
