/*******************************************************************************
 * Copyright (c) 2006, 2016 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.help.internal.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.help.HelpSystem;
import org.eclipse.help.internal.HelpData;
import org.eclipse.help.internal.HelpPlugin;
import org.osgi.framework.Bundle;

import com.ibm.icu.text.Collator;

/*
 * Reads and processes product preferences by considering not only the active
 * product, but all installed products.
 *
 * For example, help orders the books in the table of contents in such a way that
 * satisfies the currently running product's preferred order, and as many other product's
 * preferred orderings.
 */
public class ProductPreferences {

	private static Properties[] productPreferences;
	private static SequenceResolver<String> orderResolver;
	private static Map<Properties, String> preferencesToPluginIdMap;
	private static Map<Properties, String> preferencesToProductIdMap;
	private static List<String> primaryTocOrdering;
	private static List<String>[] secondaryTocOrderings;
	private static final String PLUGINS_ROOT_SLASH = "PLUGINS_ROOT/"; //$NON-NLS-1$
	private static boolean rtl;
	private static boolean directionInitialized = false;

	/*
	 * Returns the recommended order to display the given toc entries in. Each
	 * toc entry is a String, either the id of the toc contribution or the
	 * id of the category of tocs.
	 */
	public static List<String> getTocOrder(List<String> itemsToOrder, Map<String, String> nameIdMap) {
		List<String> primaryOrdering = getPrimaryTocOrdering();
		@SuppressWarnings("unchecked")
		List<String>[] secondaryOrdering = new List[0];
		if (primaryOrdering == null || primaryOrdering.size() == 0) {
			secondaryOrdering = getSecondaryTocOrderings();
		}
		return getOrderedList(itemsToOrder, primaryOrdering, secondaryOrdering, nameIdMap);
	}

	/*
	 * Returns the primary toc ordering. This is the preferred order for the active
	 * product (either specified via help data xml file or deprecated comma-separated
	 * list in plugin_customization.ini). Help data takes precedence.
	 */
	public static List<String> getPrimaryTocOrdering() {
		if (primaryTocOrdering == null) {
			IProduct product = Platform.getProduct();
			String pluginId = null;
			if (product != null) {
				pluginId = product.getDefiningBundle().getSymbolicName();
			}
			String helpDataFile = Platform.getPreferencesService().getString(HelpPlugin.PLUGIN_ID, HelpPlugin.HELP_DATA_KEY, "", null); //$NON-NLS-1$
			String baseTOCS = Platform.getPreferencesService().getString(HelpPlugin.PLUGIN_ID, HelpPlugin.BASE_TOCS_KEY, "", null); //$NON-NLS-1$
			primaryTocOrdering = getTocOrdering(pluginId, helpDataFile, baseTOCS);
			// active product has no preference for toc order
			if (primaryTocOrdering == null) {
				primaryTocOrdering = new ArrayList<>();
			}
		}
		return primaryTocOrdering;
	}

	/*
	 * Returns all secondary toc ordering. These are the preferred toc orders of all
	 * defined products except the active product.
	 */
	@SuppressWarnings("unchecked")
	public static List<String>[] getSecondaryTocOrderings() {
		if (secondaryTocOrderings == null) {
			List<List<String>> list = new ArrayList<>();
			Properties[] productPreferences = getProductPreferences(false);
			for (int i=0;i<productPreferences.length;++i) {
				String pluginId = preferencesToPluginIdMap.get(productPreferences[i]);
				String helpDataFile = (String)productPreferences[i].get(HelpPlugin.PLUGIN_ID + '/' + HelpPlugin.HELP_DATA_KEY);
				String baseTOCS = (String)productPreferences[i].get(HelpPlugin.PLUGIN_ID + '/' + HelpPlugin.BASE_TOCS_KEY);
				List<String> ordering = getTocOrdering(pluginId, helpDataFile, baseTOCS);
				if (ordering != null) {
					list.add(ordering);
				}
			}
			// can't instantiate arrays of generic type
			secondaryTocOrderings = list.toArray(new List[list.size()]);
		}
		return secondaryTocOrderings;
	}

	/*
	 * Returns the preferred toc ordering of the product defined by the given
	 * plug-in that has the given helpDataFile and baseTOCS specified (these last
	 * two may be null if not specified).
	 */
	public static List<String> getTocOrdering(String pluginId, String helpDataFile, String baseTOCS) {
		if (helpDataFile != null && helpDataFile.length() > 0) {
			String helpDataPluginId = pluginId;
			String helpDataPath = helpDataFile;
			if (helpDataFile.startsWith(PLUGINS_ROOT_SLASH)) {
				int nextSlash = helpDataFile.indexOf('/', PLUGINS_ROOT_SLASH.length());
				if (nextSlash > 0) {
					helpDataPluginId = helpDataFile.substring(PLUGINS_ROOT_SLASH.length(), nextSlash);
				    helpDataPath = helpDataFile.substring(nextSlash + 1);
				}
			}
			Bundle bundle = null;
			if (helpDataPluginId != null) {
				bundle = Platform.getBundle(helpDataPluginId);
			}
			if (bundle != null) {
			    URL helpDataUrl = bundle.getEntry(helpDataPath);
			    HelpData helpData = new HelpData(helpDataUrl);
			    return helpData.getTocOrder();
			}
		}
		else {
			if (baseTOCS != null) {
				return tokenize(baseTOCS);
			}
		}
		return null;
	}

	/*
	 * Uses the preference service to get the preference. This has changed slightly in Eclipse 3.5.
	 * The old behavior was undocumented and I think incorrect - CG.
	 *
	 * Previous behavior:
	 * Returns the boolean preference for the given key by consulting every
	 * product's preferences. If any of the products want the preference to
	 * be true (or use the default and the default is true), returns true.
	 * Otherwise returns false (if no products want it true).
	 */
	public static boolean getBoolean(Plugin plugin, String key) {
		return Platform.getPreferencesService().getBoolean(plugin.getBundle().getSymbolicName(), key, false, null);
		/*
		Properties[] properties = getProductPreferences(true);
		String defaultValue = plugin.getPluginPreferences().getDefaultString(key);
		String currentValue = plugin.getPluginPreferences().getString(key);
		String pluginId = plugin.getBundle().getSymbolicName();
		if (currentValue != null && currentValue.equalsIgnoreCase(TRUE)) {
			return true;
		}
		for (int i=0;i<properties.length;++i) {
			String value = (String)properties[i].get(pluginId + '/' + key);
			if (value == null) {
				value = defaultValue;
			}
			if (value != null && value.equalsIgnoreCase(TRUE)) {
				return true;
			}
		}
		return false;
		*/
	}

	/*
	 * Returns the given items in the order specified. Items listed in the order
	 * but not present are skipped, and items present but not ordered are added
	 * at the end.
	 */
	public static List<String> getOrderedList(List<String> items, List<String> order) {
		return getOrderedList(items, order, null, null);
	}

	/*
	 * Returns the given items in an order that best satisfies the given orderings.
	 * The primary ordering must be satisfied in all cases. As many secondary orderings
	 * as reasonably possible will be satisfied.
	 */
	public static List<String> getOrderedList(List<String> items, List<String> primary, List<String>[] secondary,
			Map<String, String> nameIdMap) {
		List<String> result = new ArrayList<>();
		List<String> set = new ArrayList<>(items);
		if (orderResolver == null) {
			orderResolver = new SequenceResolver<>();
		}
		List<String> order = orderResolver.getSequence(primary, secondary);
		for (String obj : order) {
			if (set.contains(obj)) {
				result.add(obj);
				set.remove(obj);
			}
		}
		if (HelpData.getProductHelpData().isSortOthers() && nameIdMap != null) {
			List<String> remaining = new ArrayList<>();
			remaining.addAll(set);
			sortByName(remaining, nameIdMap);
			result.addAll(remaining);
		} else {
			result.addAll(set);
		}
		return result;
	}

	private static class NameComparator implements Comparator<String> {

		private Map<String, String> tocNames;

		public NameComparator(Map<String, String> tocNames) {
			this.tocNames = tocNames;
		}

		@Override
		public int compare(String o1, String o2) {
			Object name1 = tocNames.get(o1);
			Object name2 = tocNames.get(o2);
			if (!(name1 instanceof String)) {
				return (name2 instanceof String) ? -1 : 0;
			}
			if (!(name2 instanceof String)) {
				return 1;
			}
			return Collator.getInstance().compare((String)name1, (String)name2);
		}

	}

	private static void sortByName(List<String> remaining, Map<String, String> categorized) {
		Collections.sort(remaining, new NameComparator(categorized));
	}

	public static synchronized String getPluginId(Properties prefs) {
		return preferencesToPluginIdMap.get(prefs);
	}

	public static synchronized String getProductId(Properties prefs) {
		return preferencesToProductIdMap.get(prefs);
	}

	/*
	 * Returns the preferences for all products in the runtime environment (even if
	 * they are not active).
	 */
	public static synchronized Properties[] getProductPreferences(boolean includeActiveProduct) {
		if (productPreferences == null) {
			String activeProductId = null;
			IProduct activeProduct = Platform.getProduct();
			if (activeProduct != null) {
				activeProductId = activeProduct.getId();
			}
			Collection<Properties> collection = new ArrayList<>();
			IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.core.runtime.products"); //$NON-NLS-1$
			for (int i=0;i<elements.length;++i) {
				if (elements[i].getName().equals("product")) { //$NON-NLS-1$
					String productId = elements[i].getDeclaringExtension().getUniqueIdentifier();
					if (includeActiveProduct || activeProductId == null || !activeProductId.equals(productId)) {
						String contributor = elements[i].getContributor().getName();
						IConfigurationElement[] propertyElements = elements[i].getChildren("property"); //$NON-NLS-1$
						for (int j=0;j<propertyElements.length;++j) {
							String name = propertyElements[j].getAttribute("name"); //$NON-NLS-1$
							if (name != null && name.equals("preferenceCustomization")) { //$NON-NLS-1$
								String value = propertyElements[j].getAttribute("value"); //$NON-NLS-1$
								if (value != null) {
									Properties properties = loadPropertiesFile(contributor, value);
									if (properties != null) {
										collection.add(properties);
									}
									if (preferencesToPluginIdMap == null) {
										preferencesToPluginIdMap = new HashMap<>();
									}
									preferencesToPluginIdMap.put(properties, contributor);
									if (preferencesToProductIdMap == null) {
										preferencesToProductIdMap = new HashMap<>();
									}
									preferencesToProductIdMap.put(properties, productId);
								}
							}
						}
					}
				}
			}
			productPreferences = collection.toArray(new Properties[collection.size()]);
		}
		return productPreferences;
	}

	/*
	 * Returns the value for the given key by consulting the given properties, but giving
	 * precedence to the primary properties. If the primary properties has the key, it is
	 * returned. Otherwise, it will return the value of the first secondary properties that
	 * has the key, or null if none of them has it.
	 */
	public static String getValue(String key, Properties primary, Properties[] secondary) {
		String value = null;
		if (primary != null) {
			value = primary.getProperty(key);
		}
		if (value == null) {
			for (int i=0;i<secondary.length;++i) {
				if (secondary[i] != primary) {
					value = secondary[i].getProperty(key);
					if (value != null) {
						break;
					}
				}
			}
		}
		return value;
	}

	/*
	 * Loads and returns the properties in the given properties file. The path is
	 * relative to the bundle with the given id.
	 */
	public static Properties loadPropertiesFile(String bundleId, String path) {
		Bundle bundle = Platform.getBundle(bundleId);
		if (bundle != null) {
			URL url = bundle.getEntry(path);
			if (url != null) {
				try (InputStream in = url.openStream()) {
					Properties properties = new Properties();
					properties.load(in);
					return properties;
				} catch (IOException e) {
					// log the fact that it couldn't load it
					HelpPlugin.logError("Error opening product's plugin customization file: " + bundleId + "/" + path, e); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}
		return null;
	}

	/*
	 * Tokenizes the given list of items, allowing them to be separated by whitespace, commas,
	 * and/or semicolons.
	 *
	 * e.g. "item1, item2, item3"
	 * would return a list of strings containing "item1", "item2", and "item3".
	 */
	public static List<String> tokenize(String str) {
		if (str != null) {
			StringTokenizer tok = new StringTokenizer(str, " \n\r\t;,"); //$NON-NLS-1$
			List<String> list = new ArrayList<>();
			while (tok.hasMoreElements()) {
				list.add(tok.nextToken());
			}
			return list;
		}
		return new ArrayList<>();
	}

	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		return 0;
	}

	public static void resetPrimaryTocOrdering() {
		primaryTocOrdering = null;
	}

	public static boolean isRTL() {
		if (!directionInitialized) {
			directionInitialized = true;
			rtl = initializeRTL();
		}
		return rtl;
	}

	private static boolean initializeRTL() {
		// from property
		String orientation = System.getProperty("eclipse.orientation"); //$NON-NLS-1$
		if ("rtl".equals(orientation)) { //$NON-NLS-1$
			return true;
		} else if ("ltr".equals(orientation)) { //$NON-NLS-1$
			return false;
		}
		// from command line
		String[] args = Platform.getCommandLineArgs();
		for (int i = 0; i < args.length; i++) {
			if ("-dir".equalsIgnoreCase(args[i])) { //$NON-NLS-1$
				if ((i + 1) < args.length
						&& "rtl".equalsIgnoreCase(args[i + 1])) { //$NON-NLS-1$
					return true;
				}
				return false;
			}
		}

		// Check if the user property is set. If not do not
		// rely on the vm.
		if (System.getProperty("osgi.nl.user") == null) //$NON-NLS-1$
			return false;

		// guess from default locale
		String locale = Platform.getNL();
		if (locale == null) {
			locale = Locale.getDefault().toString();
		}
		if (locale.startsWith("ar") || locale.startsWith("fa") //$NON-NLS-1$//$NON-NLS-2$
				|| locale.startsWith("he") || locale.startsWith("iw") //$NON-NLS-1$//$NON-NLS-2$
				|| locale.startsWith("ur")) { //$NON-NLS-1$
			return true;
		}
		return false;
	}

	/*
	 * Expand the special identifiers PLUGINS_ROOT and PRODUCT_PLUGIN in a path
	 */
	public static String resolveSpecialIdentifiers(String path) {
		if (path == null) {
			return null;
		}
		int index = path.indexOf("PLUGINS_ROOT"); //$NON-NLS-1$
		if (index != -1) {
			path = path.substring(index + "PLUGINS_ROOT".length()); //$NON-NLS-1$
		}
		index = path.indexOf('/', 1);
		if (index != -1) {
			String bundleName = path.substring(0, index);
			if ("PRODUCT_PLUGIN".equals(bundleName) || "/PRODUCT_PLUGIN".equals(bundleName)) { //$NON-NLS-1$ //$NON-NLS-2$
				IProduct product = Platform.getProduct();
				if (product != null) {
					Bundle productBundle = product.getDefiningBundle();
					if (productBundle != null) {
						bundleName = productBundle.getSymbolicName();
						return '/' + bundleName + path.substring(index);
					}
				}
			}
		}
		return path;
	}

	public static boolean useEnablementFilters() {
		if (!HelpSystem.isShared()) {
			return true;
		}
		return Platform.getPreferencesService().getBoolean(HelpPlugin.PLUGIN_ID, HelpPlugin.FILTER_INFOCENTER_KEY, false, null);
	}
}
