/*******************************************************************************
 * Copyright (c) 2006, 2015 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.Collection;
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 extensionsByPath;
	private Map replacesByPath;

	/*
	 * Returns all known extensions for the given locale.
	 */
	public ContentExtension[] getExtensions(String locale) {
		if (extensionsByPath == null) {
			loadExtensions(locale);
		}
		List extensions = new ArrayList();
		Iterator iter = extensionsByPath.values().iterator();
		while (iter.hasNext()) {
			extensions.addAll((Collection)iter.next());
		}
		iter = replacesByPath.values().iterator();
		while (iter.hasNext()) {
			extensions.addAll((Collection)iter.next());
		}
		return (ContentExtension[])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 map = (type == ContentExtension.CONTRIBUTION ? extensionsByPath : replacesByPath);
		List extensions = (List)map.get(path);
		if (extensions != null) {
			return (ContentExtension[])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 map = (type == IContentExtension.CONTRIBUTION ? extensionsByPath : replacesByPath);
					content = normalizePath(content);
					path = normalizePath(path);
					extension.setContent(content);
					extension.setPath(path);
					List list = (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 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 = (AbstractContentExtensionProvider[])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;
	}
}
