/*******************************************************************************
 * Copyright (c) 2008, 2018 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
 *     EclipseSource - ongoing development
 *     Cloudsmith Inc. - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.metadata;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
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.p2.metadata.ICopyright;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
import org.eclipse.equinox.p2.metadata.ILicense;
import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
import org.eclipse.equinox.p2.metadata.KeyWithLocale;
import org.eclipse.equinox.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.metadata.expression.IExpressionFactory;
import org.eclipse.equinox.p2.query.Collector;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.IQueryable;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.osgi.service.localization.LocaleProvider;

/**
 * TranslationSupport provides string translations for properties of an 
 * IInstallableUnit.  Clients can specify an {@link IQueryable} that should be used
 * to obtain the translation fragment IU's, as well as the locale that
 * should be used for translations.
 * 
 * @since 2.0
 */
public class TranslationSupport {
	// 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$

	public static final String PI_METADATA = "org.eclipse.equinox.p2.metadata"; //$NON-NLS-1$

	private static TranslationSupport instance;

	static final String NAMESPACE_IU_LOCALIZATION = "org.eclipse.equinox.p2.localization"; //$NON-NLS-1$
	private IQueryable<IInstallableUnit> fragmentSource;

	private static IExpression capabilityMatch = ExpressionUtil.parse("providedCapabilities.exists(x | x.namespace == $0 && $1.exists(n | x.name == n))"); //$NON-NLS-1$
	private static IExpression haveHostMatch = ExpressionUtil.parse("host.exists(h | $0 ~= h)"); //$NON-NLS-1$

	// Cache the IU fragments that provide localizations for a given locale.
	// Map<String,SoftReference<IQueryResult>>: locale => soft reference to a queryResult
	private final Map<String, SoftReference<IQueryResult<IInstallableUnit>>> localeCollectorCache = new HashMap<>(2);

	private LocaleProvider localeProvider;
	private boolean loggedMissingSource = false;

	public synchronized static TranslationSupport getInstance() {
		if (instance == null)
			instance = new TranslationSupport();
		return instance;
	}

	/**
	 * Create an instance of TranslationSupport for the current locale.
	 * Unless otherwise specified, the currently running profile will serve
	 * as the source of the translation fragments.
	 * 
	 * @since 2.0
	 */
	public TranslationSupport() {
		super();
	}

	/**
	 * Create an instance of TranslationSupport for the current locale.
	 * using the <code>fragmentSource</code> as the source of the translation fragments.
	 * 
	 * @since 2.0
	 */
	public TranslationSupport(IQueryable<IInstallableUnit> fragmentSource) {
		this.fragmentSource = fragmentSource;
	}

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

	/**
	 * 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 String cacheResult(IInstallableUnit iu, String localizedKey, String localizedValue) {
		if (iu instanceof InstallableUnit)
			((InstallableUnit) iu).setLocalizedProperty(localizedKey, localizedValue);
		return localizedValue;
	}

	/**
	 * Return the copyright for the specified IInstallableUnit, 
	 * localized for the receiver's locale.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @return the localized copyright defined by the IInstallableUnit
	 */
	public ICopyright getCopyright(IInstallableUnit iu, String locale) {
		if (locale == null)
			locale = getCurrentLocale();
		ICopyright 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);
		return MetadataFactory.createCopyright(copyright.getLocation(), body);
	}

	private String getCurrentLocale() {
		if (localeProvider != null)
			return localeProvider.getLocale().toString();
		return Locale.getDefault().toString();
	}

	/**
	 * Return the localized value for the specified IInstallableUnit
	 * property.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @param propertyKey the name of the property to be retrieved
	 * @param locale The locale to return the property for
	 * @return the localized property value, or <code>null</code> if no
	 * such property is defined.
	 */
	public String getIUProperty(IInstallableUnit iu, String propertyKey, String locale) {
		if (locale == null)
			locale = getCurrentLocale();
		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);
	}

	/**
	 * Return the localized value for the specified IInstallableUnit
	 * property using the locale specified in the <code>propertyKey</code>.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @param propertyKey the name and locale of the property to be retrieved
	 * @return the localized property value, or <code>null</code> if no
	 * such property is defined.
	 */
	public String getIUProperty(IInstallableUnit iu, KeyWithLocale propertyKey) {
		return getIUProperty(iu, propertyKey.getKey(), propertyKey.getLocale().toString());
	}

	/**
	 * Return the localized value for the specified IInstallableUnit
	 * property using the default locale.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @param propertyKey the name of the property to be retrieved
	 * @return the localized property value, or <code>null</code> if no
	 * such property is defined.
	 */
	public String getIUProperty(IInstallableUnit iu, String propertyKey) {
		return getIUProperty(iu, propertyKey, null);
	}

	private ILicense getLicense(IInstallableUnit iu, ILicense license, String locale) {
		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);
		return MetadataFactory.createLicense(license.getLocation(), body);
	}

	/**
	 * Return an array of licenses for the specified IInstallableUnit, 
	 * localized for the receiver's locale.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @return the localized licenses defined by the IInstallableUnit
	 */
	public ILicense[] getLicenses(IInstallableUnit iu, String locale) {
		if (locale == null)
			locale = getCurrentLocale();
		Collection<ILicense> licenses = iu.getLicenses();
		ILicense[] translatedLicenses = new ILicense[licenses.size()];
		int i = 0;
		for (ILicense iLicense : licenses) {
			translatedLicenses[i++] = getLicense(iu, iLicense, locale);
		}
		return translatedLicenses;
	}

	/**
	 * Return an update descriptor localized for the receiver's locale.
	 * 
	 * @param iu the IInstallableUnit in question
	 * @return the localized update descriptor defined by the IInstallableUnit
	 */
	public IUpdateDescriptor getUpdateDescriptor(IInstallableUnit iu, String locale) {
		if (locale == null)
			locale = getCurrentLocale();

		IUpdateDescriptor descriptor = iu.getUpdateDescriptor();
		String body = (descriptor != null ? descriptor.getDescription() : null);
		if (body == null || body.length() <= 1 || body.charAt(0) != '%')
			return descriptor;
		final String actualKey = body.substring(1); // Strip off the %
		body = getLocalizedIUProperty(iu, actualKey, locale);
		return MetadataFactory.createUpdateDescriptor(descriptor.getIUsBeingUpdated(), descriptor.getSeverity(), body, descriptor.getLocation());
	}

	/**
	 * Collects the installable unit fragments that contain locale data for the given locales.
	 */
	private synchronized IQueryResult<IInstallableUnit> getLocalizationFragments(List<String> localeVariants, String locale) {
		if (fragmentSource == null) {
			if (!loggedMissingSource) {
				loggedMissingSource = true;
				LogHelper.log(new Status(IStatus.INFO, PI_METADATA, "No translation source unavailable. Default language will be used.")); //$NON-NLS-1$
			}
			return Collector.emptyCollector();
		}

		SoftReference<IQueryResult<IInstallableUnit>> queryResultReference = localeCollectorCache.get(locale);
		if (queryResultReference != null) {
			IQueryResult<IInstallableUnit> cached = queryResultReference.get();
			if (cached != null)
				return cached;
		}

		IQuery<IInstallableUnit> iuQuery = QueryUtil.createMatchQuery(IInstallableUnitFragment.class, capabilityMatch, NAMESPACE_IU_LOCALIZATION, localeVariants);
		IQueryResult<IInstallableUnit> collected = fragmentSource.query(iuQuery, null);
		localeCollectorCache.put(locale, new SoftReference<>(collected));
		return collected;
	}

	private String getLocalizedIUProperty(IInstallableUnit iu, String actualKey, String locale) {
		String localizedKey = makeLocalizedKey(actualKey, locale);
		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<String> locales = buildLocaleVariants(locale);
		final IInstallableUnit theUnit = iu;

		IQueryResult<IInstallableUnit> localizationFragments = getLocalizationFragments(locales, locale);

		IExpressionFactory factory = ExpressionUtil.getFactory();
		IQuery<IInstallableUnit> iuQuery = QueryUtil.createMatchQuery(IInstallableUnitFragment.class, factory.matchExpression(haveHostMatch, theUnit));
		IQueryResult<IInstallableUnit> collected = iuQuery.perform(localizationFragments.iterator());
		if (!collected.isEmpty()) {
			String translation = null;
			for (Iterator<IInstallableUnit> iter = collected.iterator(); iter.hasNext() && translation == null;) {
				IInstallableUnit localizationIU = iter.next();
				for (String unitlocale : locales) {
					String localeKey = makeLocalizedKey(actualKey, unitlocale);
					translation = localizationIU.getProperty(localeKey);
					if (translation != null)
						return cacheResult(iu, localizedKey, translation);
				}
			}
		}

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

		return cacheResult(iu, localizedKey, actualKey);
	}

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

	/**
	 * Set the locale that should be used when obtaining translations.
	 * @param provider the locale for which translations should be retrieved.
	 */
	public synchronized void setLocaleProvider(LocaleProvider provider) {
		if (provider != this.localeProvider) {
			this.localeProvider = provider;
			localeCollectorCache.clear();
		}
	}

	/**
	 * Set the {@link IQueryable} that should be used to obtain translation fragment
	 * IUs. Returns the previous translation source.
	 * 
	 * @param queryable an {@link IQueryable} that can supply the appropriate NLS
	 * translation fragments
	 */
	public synchronized IQueryable<IInstallableUnit> setTranslationSource(IQueryable<IInstallableUnit> queryable) {
		IQueryable<IInstallableUnit> previous = fragmentSource;
		if (previous != queryable) {
			this.fragmentSource = queryable;
			localeCollectorCache.clear();
		}
		return previous;
	}
}
