/*******************************************************************************
 * 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.extension;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.help.AbstractContentExtensionProvider;
import org.eclipse.help.IContentExtension;
import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.UAElementFactory;

/*
 * Manages content extensions (contributions into anchors and element
 * replacements) for user assistance documents.
 */
public class ContentExtensionManager {

	private static final String EXTENSION_POINT_ID_CONTENT_EXTENSION = HelpPlugin.PLUGIN_ID + ".contentExtension"; //$NON-NLS-1$
	private static final String ELEMENT_NAME_CONTENT_EXTENSION_PROVIDER = "contentExtensionProvider"; //$NON-NLS-1$
	private static final String ATTRIBUTE_NAME_CLASS = "class"; //$NON-NLS-1$
	private static final ContentExtension[] EMPTY_ARRAY = new ContentExtension[0];

	private AbstractContentExtensionProvider[] contentExtensionProviders;
	private Map<String, List<ContentExtension>> extensionsByPath;
	private Map<String, List<ContentExtension>> replacesByPath;

	/*
	 * Returns all known extensions for the given locale.
	 */
	public ContentExtension[] getExtensions(String locale) {
		if (extensionsByPath == null) {
			loadExtensions(locale);
		}
		List<ContentExtension> extensions = new ArrayList<>();
		Iterator<List<ContentExtension>> iter = extensionsByPath.values().iterator();
		while (iter.hasNext()) {
			extensions.addAll(iter.next());
		}
		iter = replacesByPath.values().iterator();
		while (iter.hasNext()) {
			extensions.addAll(iter.next());
		}
		return extensions.toArray(new ContentExtension[extensions.size()]);
	}

	/*
	 * Get all extensions of the given type whose target matches the given path.
	 */
	public ContentExtension[] getExtensions(String path, int type, String locale) {
		if (extensionsByPath == null) {
			loadExtensions(locale);
		}
		Map<String, List<ContentExtension>> map = (type == IContentExtension.CONTRIBUTION ? extensionsByPath
				: replacesByPath);
		List<ContentExtension> extensions = map.get(path);
		if (extensions != null) {
			return extensions.toArray(new ContentExtension[extensions.size()]);
		}
		return EMPTY_ARRAY;
	}

	/*
	 * Clears all cached data, forcing the manager to query the
	 * providers again next time a request is made.
	 */
	public void clearCache() {
		if (extensionsByPath != null) {
			extensionsByPath.clear();
		}
		if (replacesByPath != null) {
			replacesByPath.clear();
		}
	}

	/*
	 * Retrieves all extensions from all providers and organizes them by
	 * type.
	 */
	private void loadExtensions(String locale) {
		extensionsByPath = new HashMap<>();
		replacesByPath = new HashMap<>();
		contentExtensionProviders = getContentExtensionProviders();
		for (int i=0;i<contentExtensionProviders.length;++i) {
			IContentExtension[] extensions = contentExtensionProviders[i].getContentExtensions(locale);
			for (int j=0;j<extensions.length;++j) {
				ContentExtension extension = (extensions[j] instanceof ContentExtension ? (ContentExtension)extensions[j] : (ContentExtension)UAElementFactory.newElement(extensions[j]));
				String content = extension.getContent();
				String path = extension.getPath();
				if (content != null && path != null) {
					int type = extension.getType();
					Map<String, List<ContentExtension>> map = (type == IContentExtension.CONTRIBUTION ? extensionsByPath
							: replacesByPath);
					content = normalizePath(content);
					path = normalizePath(path);
					extension.setContent(content);
					extension.setPath(path);
					List<ContentExtension> list = map.get(path);
					if (list == null) {
						list = new ArrayList<>();
						map.put(path, list);
					}
					list.add(extension);
				}
			}
		}
	}

	/*
	 * Returns all registered content extension providers (potentially cached).
	 */
	private AbstractContentExtensionProvider[] getContentExtensionProviders() {
		if (contentExtensionProviders == null) {
			List<AbstractContentExtensionProvider> providers = new ArrayList<>();
			IExtensionRegistry registry = Platform.getExtensionRegistry();
			IConfigurationElement[] elements = registry.getConfigurationElementsFor(EXTENSION_POINT_ID_CONTENT_EXTENSION);
			for (int i=0;i<elements.length;++i) {
				IConfigurationElement elem = elements[i];
				if (elem.getName().equals(ELEMENT_NAME_CONTENT_EXTENSION_PROVIDER)) {
					try {
						AbstractContentExtensionProvider provider = (AbstractContentExtensionProvider)elem.createExecutableExtension(ATTRIBUTE_NAME_CLASS);
						providers.add(provider);
					}
					catch (CoreException e) {
						// log and skip
						String msg = "Error instantiating user assistance content extension provider class \"" + elem.getAttribute(ATTRIBUTE_NAME_CLASS) + '"'; //$NON-NLS-1$
						HelpPlugin.logError(msg, e);
					}
				}
			}
			contentExtensionProviders = providers.toArray(new AbstractContentExtensionProvider[providers.size()]);
		}
		return contentExtensionProviders;
	}

	/*
	 * Normalizes the given path by adding a leading slash if one doesn't
	 * exist, and converting the final slash into a '#' if it is thought to
	 * separate the end of the document with the element (legacy form).
	 */
	private String normalizePath(String path) {
		int bundleStart, bundleEnd;
		int pathStart, pathEnd;
		int elementStart, elementEnd;

		bundleStart = path.charAt(0) == '/' ? 1 : 0;
		bundleEnd = path.indexOf('/', bundleStart);

		pathStart = bundleEnd + 1;
		pathEnd = path.indexOf('#', pathStart);
		if (pathEnd == -1) {
			int lastSlash = path.lastIndexOf('/');
			if (lastSlash > 0) {
				int secondLastSlash = path.lastIndexOf('/', lastSlash - 1);
				if (secondLastSlash != -1) {
					String secondLastToken = path.substring(secondLastSlash, lastSlash);
					boolean hasDot = (secondLastToken.indexOf('.') != -1);
					if (hasDot) {
						pathEnd = lastSlash;
					}
				}
			}
			if (pathEnd == -1) {
				pathEnd = path.length();
			}
		}

		elementStart = Math.min(pathEnd + 1, path.length());
		elementEnd = path.length();

		if (bundleEnd > bundleStart && pathStart > bundleEnd && pathEnd > pathStart && elementStart >= pathEnd && elementEnd >= elementStart) {
			String bundleId = path.substring(bundleStart, bundleEnd);
			String relativePath = path.substring(pathStart, pathEnd);
			String elementId = path.substring(elementStart, elementEnd);
			path = '/' + bundleId + '/' + relativePath;
			if (elementId.length() > 0) {
				path += '#' + elementId;
			}
		}
		return path;
	}
}
