/*******************************************************************************
 * Copyright (c) 2008 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.ui.query;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry;
import org.eclipse.equinox.internal.provisional.p2.metadata.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.IUPropertyQuery;
import org.eclipse.equinox.internal.provisional.p2.query.Collector;

public class IUPropertyUtils {

	// TODO: these constants should come from API, eg. IInstallableUnit or ???
	static final Locale DEFAULT_LOCALE = new Locale("df", "LT"); //$NON-NLS-1$//$NON-NLS-2$
	static final String NAMESPACE_IU_LOCALIZATION = "org.eclipse.equinox.p2.localization"; //$NON-NLS-1$

	// Cache the IU fragments that provide localizations for a given locale.
	//    map: locale => soft reference to a collector
	private static Map LocaleCollectorCache = new HashMap(2);

	// Get the license in the default locale.
	public static License getLicense(IInstallableUnit iu) {
		return getLicense(iu, getCurrentLocale());
	}

	// Get the copyright in the default locale.
	public static Copyright getCopyright(IInstallableUnit iu) {
		return getCopyright(iu, getCurrentLocale());
	}

	// Get a property in the default locale
	public static String getIUProperty(IInstallableUnit iu, String propertyKey) {
		return getIUProperty(iu, propertyKey, getCurrentLocale());
	}

	public static License getLicense(IInstallableUnit iu, Locale locale) {
		License license = iu.getLicense();
		String body = (license != null ? license.getBody() : null);
		if (body == null || body.length() <= 1 || body.charAt(0) != '%')
			return license;
		final String actualKey = body.substring(1); // Strip off the %
		body = getLocalizedIUProperty(iu, actualKey, locale);
		URL url = license.getURL();
		return new License((url != null ? url.toExternalForm() : null), body);
	}

	public static Copyright getCopyright(IInstallableUnit iu, Locale locale) {
		Copyright copyright = iu.getCopyright();
		String body = (copyright != null ? copyright.getBody() : null);
		if (body == null || body.length() <= 1 || body.charAt(0) != '%')
			return copyright;
		final String actualKey = body.substring(1); // Strip off the %
		body = getLocalizedIUProperty(iu, actualKey, locale);
		URL url = copyright.getURL();
		return new Copyright((url != null ? url.toExternalForm() : null), body);
	}

	public static String getIUProperty(IInstallableUnit iu, String propertyKey, Locale locale) {
		String value = iu.getProperty(propertyKey);
		if (value == null || value.length() <= 1 || value.charAt(0) != '%')
			return value;
		// else have a localizable property
		final String actualKey = value.substring(1); // Strip off the %
		return getLocalizedIUProperty(iu, actualKey, locale);
	}

	private static String getLocalizedIUProperty(IInstallableUnit iu, String actualKey, Locale locale) {
		String localizedKey = makeLocalizedKey(actualKey, locale.toString());
		String localizedValue = null;

		//first check for a cached localized value
		if (iu instanceof InstallableUnit)
			localizedValue = ((InstallableUnit) iu).getLocalizedProperty(localizedKey);
		//next check if the localized value is stored in the same IU (common case)
		if (localizedValue == null)
			localizedValue = iu.getProperty(localizedKey);
		if (localizedValue != null)
			return localizedValue;

		final List locales = buildLocaleVariants(locale);
		final IInstallableUnit theUnit = iu;

		Collector localizationFragments = getLocalizationFragments(locale, locales);

		Collector hostLocalizationCollector = new Collector() {
			public boolean accept(Object object) {
				boolean haveHost = false;
				if (object instanceof IInstallableUnitFragment) {
					IInstallableUnitFragment fragment = (IInstallableUnitFragment) object;
					RequiredCapability[] hosts = fragment.getHost();
					for (int i = 0; i < hosts.length; i++) {
						RequiredCapability nextHost = hosts[i];
						if (IInstallableUnit.NAMESPACE_IU_ID.equals(nextHost.getNamespace()) && //
								theUnit.getId().equals(nextHost.getName()) && //
								nextHost.getRange() != null && //
								nextHost.getRange().isIncluded(theUnit.getVersion())) {
							haveHost = true;
							break;
						}
					}
				}
				return (haveHost ? super.accept(object) : false);
			}
		};

		IUPropertyQuery iuQuery = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_FRAGMENT, "true"); //$NON-NLS-1$
		Collector collected = iuQuery.perform(localizationFragments.iterator(), hostLocalizationCollector);

		if (!collected.isEmpty()) {
			String translation = null;
			for (Iterator iter = collected.iterator(); iter.hasNext() && translation == null;) {
				IInstallableUnit localizationIU = (IInstallableUnit) iter.next();
				for (Iterator jter = locales.iterator(); jter.hasNext();) {
					String localeKey = makeLocalizedKey(actualKey, (String) jter.next());
					translation = localizationIU.getProperty(localeKey);
					if (translation != null)
						return cacheResult(iu, localizedKey, translation);
				}
			}
		}

		for (Iterator iter = locales.iterator(); iter.hasNext();) {
			String nextLocale = (String) iter.next();
			String localeKey = makeLocalizedKey(actualKey, nextLocale);
			String nextValue = iu.getProperty(localeKey);
			if (nextValue != null)
				return cacheResult(iu, localizedKey, nextValue);
		}

		return cacheResult(iu, localizedKey, actualKey);
	}

	/**
	 * Cache the translated property value to optimize future retrieval of the same value.
	 * Currently we just cache on the installable unit object in memory. In future
	 * we should push support for localized property retrieval into IInstallableUnit
	 * so we aren't required to reach around the API here.
	 */
	private static String cacheResult(IInstallableUnit iu, String localizedKey, String localizedValue) {
		if (iu instanceof InstallableUnit)
			((InstallableUnit) iu).setLocalizedProperty(localizedKey, localizedValue);
		return localizedValue;
	}

	/**
	 * Collects the installable unit fragments that contain locale data for the given locales.
	 */
	private static synchronized Collector getLocalizationFragments(Locale locale, List localeVariants) {
		SoftReference collectorRef = (SoftReference) LocaleCollectorCache.get(locale);
		if (collectorRef != null) {
			Collector cached = (Collector) collectorRef.get();
			if (cached != null)
				return cached;
		}

		final List locales = localeVariants;

		Collector localeFragmentCollector = new Collector() {
			public boolean accept(Object object) {
				boolean haveLocale = false;
				if (object instanceof IInstallableUnitFragment) {
					IInstallableUnitFragment fragment = (IInstallableUnitFragment) object;
					ProvidedCapability[] provides = fragment.getProvidedCapabilities();
					for (int j = 0; j < provides.length && !haveLocale; j++) {
						ProvidedCapability nextProvide = provides[j];
						if (NAMESPACE_IU_LOCALIZATION.equals(nextProvide.getNamespace())) {
							String providedLocale = nextProvide.getName();
							if (providedLocale != null) {
								for (Iterator iter = locales.iterator(); iter.hasNext();) {
									if (providedLocale.equals(iter.next())) {
										haveLocale = true;
										break;
									}
								}
							}
						}
					}
				}
				return (haveLocale ? super.accept(object) : false);
			}
		};

		//Due to performance problems we restrict locale lookup to the current profile (see bug 233958)
		IProfileRegistry profileRegistry = (IProfileRegistry) ServiceHelper.getService(ProvUIActivator.getContext(), IProfileRegistry.class.getName());
		if (profileRegistry == null) {
			LogHelper.log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, "Profile registry unavailable. Default language will be used.", new RuntimeException())); //$NON-NLS-1$
			return new Collector();
		}
		IProfile profile = profileRegistry.getProfile(IProfileRegistry.SELF);
		if (profile == null) {
			LogHelper.log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, "Profile unavailable. Default language will be used.", new RuntimeException())); //$NON-NLS-1$
			return new Collector();
		}
		IUPropertyQuery iuQuery = new IUPropertyQuery(IInstallableUnit.PROP_TYPE_FRAGMENT, "true"); //$NON-NLS-1$
		Collector collected = profile.query(iuQuery, localeFragmentCollector, null);
		LocaleCollectorCache.put(locale, new SoftReference(collected));
		return collected;
	}

	/**
	 */
	private static List buildLocaleVariants(Locale locale) {
		String nl = locale.toString();
		ArrayList result = new ArrayList(4);
		int lastSeparator;
		while (true) {
			result.add(nl);
			lastSeparator = nl.lastIndexOf('_');
			if (lastSeparator == -1)
				break;
			nl = nl.substring(0, lastSeparator);
		}
		// Add the default locale (most general)
		result.add(DEFAULT_LOCALE.toString());
		return result;
	}

	private static String makeLocalizedKey(String actualKey, String localeImage) {
		return localeImage + '.' + actualKey;
	}

	private static Locale getCurrentLocale() {
		return Locale.getDefault();
	}

}
