/*******************************************************************************
 * Copyright (c) 2004, 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.osgi.storage;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.ModuleWire;
import org.eclipse.osgi.container.ModuleWiring;
import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.osgi.framework.Constants;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.wiring.BundleRevision;

/**
 * This class is used to localize manifest headers for a revision.
 */
public class ManifestLocalization {
	final String defaultRoot;
	private final Generation generation;
	private final Dictionary<String, String> rawHeaders;
	private volatile Dictionary<String, String> defaultLocaleHeaders = null;
	private final Hashtable<String, BundleResourceBundle> cache = new Hashtable<>(5);

	public ManifestLocalization(Generation generation, Dictionary<String, String> rawHeaders, String defaultRoot) {
		this.generation = generation;
		this.rawHeaders = rawHeaders;
		this.defaultRoot = defaultRoot;
	}

	public void clearCache() {
		synchronized (cache) {
			cache.clear();
			defaultLocaleHeaders = null;
		}
	}

	Dictionary<String, String> getHeaders(String localeString) {
		if (localeString == null)
			localeString = Locale.getDefault().toString();
		if (localeString.length() == 0)
			return rawHeaders;
		boolean isDefaultLocale = localeString.equals(Locale.getDefault().toString());
		Dictionary<String, String> currentDefault = defaultLocaleHeaders;
		if (isDefaultLocale && currentDefault != null) {
			return currentDefault;
		}
		if (generation.getRevision().getRevisions().getModule().getState().equals(Module.State.UNINSTALLED)) {
			// defaultLocaleHeaders should have been initialized on uninstall
			if (currentDefault != null)
				return currentDefault;
			return rawHeaders;
		}
		ResourceBundle localeProperties = getResourceBundle(localeString, isDefaultLocale);
		CaseInsensitiveDictionaryMap<String, String> localeHeaders = new CaseInsensitiveDictionaryMap<>(this.rawHeaders);
		for (Entry<String, String> entry : localeHeaders.entrySet()) {
			String value = entry.getValue();
			if (value.startsWith("%") && (value.length() > 1)) { //$NON-NLS-1$
				String propertiesKey = value.substring(1);
				try {
					value = localeProperties == null ? propertiesKey : (String) localeProperties.getObject(propertiesKey);
				} catch (MissingResourceException ex) {
					value = propertiesKey;
				}
				entry.setValue(value);
			}
		}
		Dictionary<String, String> result = localeHeaders.asUnmodifiableDictionary();
		if (isDefaultLocale) {
			defaultLocaleHeaders = result;
		}
		return result;
	}

	private String[] buildNLVariants(String nl) {
		List<String> result = new ArrayList<>();
		while (nl.length() > 0) {
			result.add(nl);
			int i = nl.lastIndexOf('_');
			nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
		}
		result.add(""); //$NON-NLS-1$
		return result.toArray(new String[result.size()]);
	}

	/*
	 * This method find the appropriate Manifest Localization file inside the
	 * bundle. If not found, return null.
	 */
	ResourceBundle getResourceBundle(String localeString, boolean isDefaultLocale) {
		BundleResourceBundle resourceBundle = lookupResourceBundle(localeString);
		if (isDefaultLocale)
			return (ResourceBundle) resourceBundle;
		// need to determine if this is resource bundle is an empty stem
		// if it is then the default locale should be used
		if (resourceBundle == null || resourceBundle.isStemEmpty())
			return (ResourceBundle) lookupResourceBundle(Locale.getDefault().toString());
		return (ResourceBundle) resourceBundle;
	}

	private BundleResourceBundle lookupResourceBundle(String localeString) {
		// get the localization header as late as possible to avoid accessing the raw headers
		// getting the first value from the raw headers forces the manifest to be parsed (bug 332039)
		String localizationHeader = rawHeaders.get(Constants.BUNDLE_LOCALIZATION);
		if (localizationHeader == null)
			localizationHeader = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;

		BundleResourceBundle result = cache.get(localeString);
		if (result != null)
			return result.isEmpty() ? null : result;

		// Collect all the necessary inputstreams to create the resource bundle without
		// holding any locks.  Finding resources and inputstreams from the wirings requires a
		// read lock on the module database.  We must not hold the cache lock while doing this;
		// otherwise out of order locks will be possible when the resolver needs to clear the cache
		String[] nlVarients = buildNLVariants(localeString);
		InputStream[] nlStreams = new InputStream[nlVarients.length];
		for (int i = nlVarients.length - 1; i >= 0; i--) {

			URL url = findResource(localizationHeader + (nlVarients[i].equals("") ? nlVarients[i] : '_' + nlVarients[i]) + ".properties"); //$NON-NLS-1$ //$NON-NLS-2$
			if (url != null) {
				try {
					nlStreams[i] = url.openStream();
				} catch (IOException e) {
					// ignore
				}
			}
		}

		synchronized (cache) {
			BundleResourceBundle parent = null;
			for (int i = nlVarients.length - 1; i >= 0; i--) {
				BundleResourceBundle varientBundle = null;
				InputStream varientStream = nlStreams[i];
				if (varientStream == null) {
					varientBundle = cache.get(nlVarients[i]);
				} else {
					try {
						varientBundle = new LocalizationResourceBundle(varientStream);
					} catch (IOException e) {
						// ignore and continue
					} finally {
						if (varientStream != null) {
							try {
								varientStream.close();
							} catch (IOException e3) {
								//Ignore exception
							}
						}
					}
				}

				if (varientBundle == null) {
					varientBundle = new EmptyResouceBundle(nlVarients[i]);
				}
				if (parent != null)
					varientBundle.setParent((ResourceBundle) parent);
				cache.put(nlVarients[i], varientBundle);
				parent = varientBundle;
			}
			result = cache.get(localeString);
			return result.isEmpty() ? null : result;
		}
	}

	private URL findResource(String resource) {
		ModuleWiring searchWiring = generation.getRevision().getWiring();
		if (searchWiring != null) {
			if ((generation.getRevision().getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) {
				List<ModuleWire> hostWires = searchWiring.getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
				searchWiring = null;
				Long lowestHost = Long.MAX_VALUE;
				if (hostWires != null) {
					// search for the host with the highest ID
					for (ModuleWire hostWire : hostWires) {
						Long hostID = hostWire.getProvider().getRevisions().getModule().getId();
						if (hostID.compareTo(lowestHost) <= 0) {
							lowestHost = hostID;
							searchWiring = hostWire.getProviderWiring();
						}
					}
				}
			}
		}
		if (searchWiring != null) {
			int lastSlash = resource.lastIndexOf('/');
			String path = lastSlash > 0 ? resource.substring(0, lastSlash) : "/"; //$NON-NLS-1$
			String fileName = lastSlash != -1 ? resource.substring(lastSlash + 1) : resource;
			List<URL> result = searchWiring.findEntries(path, fileName, 0);
			return (result == null || result.isEmpty()) ? null : result.get(0);
		}
		// search the raw bundle file for the generation
		return generation.getEntry(resource);
	}

	private interface BundleResourceBundle {
		void setParent(ResourceBundle parent);

		boolean isEmpty();

		boolean isStemEmpty();
	}

	private class LocalizationResourceBundle extends PropertyResourceBundle implements BundleResourceBundle {
		public LocalizationResourceBundle(InputStream in) throws IOException {
			super(in);
		}

		public void setParent(ResourceBundle parent) {
			super.setParent(parent);
		}

		public boolean isEmpty() {
			return false;
		}

		public boolean isStemEmpty() {
			return parent == null;
		}
	}

	class EmptyResouceBundle extends ResourceBundle implements BundleResourceBundle {
		private final String localeString;

		public EmptyResouceBundle(String locale) {
			super();
			this.localeString = locale;
		}

		@SuppressWarnings("unchecked")
		public Enumeration<String> getKeys() {
			return Collections.enumeration(Collections.EMPTY_LIST);
		}

		protected Object handleGetObject(String arg0) throws MissingResourceException {
			return null;
		}

		public void setParent(ResourceBundle parent) {
			super.setParent(parent);
		}

		public boolean isEmpty() {
			if (parent == null)
				return true;
			return ((BundleResourceBundle) parent).isEmpty();
		}

		public boolean isStemEmpty() {
			if (defaultRoot.equals(localeString))
				return false;
			if (parent == null)
				return true;
			return ((BundleResourceBundle) parent).isStemEmpty();
		}
	}
}
