/*******************************************************************************
 * Copyright (c) 2000, 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.team.internal.ui.registry;

import java.util.Hashtable;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.Utils.Sorter;
import org.osgi.framework.Bundle;

public abstract class RegistryReader {
	protected static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$
	protected static Hashtable<String, IExtension[]> extensionPoints = new Hashtable<>();

	/**
	 * Creates an extension.  If the extension plugin has not
	 * been loaded a busy cursor will be activated during the duration of
	 * the load.
	 *
	 * @param element the configuration element defining the extension
	 * @param classAttribute the name of the attribute carrying the class
	 * @return the extension object
	 * @throws CoreException if the extension cannot be created
	 */
	public static Object createExtension(final IConfigurationElement element,
			final String classAttribute) throws CoreException {
		try {
			// If plugin has been loaded create extension.
			// Otherwise, show busy cursor then create extension.
			if (isActivated(element.getDeclaringExtension()
					.getContributor().getName())) {
				return element.createExecutableExtension(classAttribute);
			}
			final Object[] ret = new Object[1];
			final CoreException[] exc = new CoreException[1];
			BusyIndicator.showWhile(null, () -> {
				try {
					ret[0] = element
							.createExecutableExtension(classAttribute);
				} catch (CoreException e) {
					exc[0] = e;
				}
			});
			if (exc[0] != null) {
				throw exc[0];
			}
			return ret[0];

		} catch (CoreException core) {
			throw core;
		} catch (Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, TeamUIPlugin.ID,
					IStatus.ERROR, NLS.bind(TeamUIMessages.RegistryReader_0, element.getNamespaceIdentifier(), element.getName()),e));
		}
	}

	private static boolean isActivated(String bundleId) {
		return isActivated(Platform.getBundle(bundleId));
	}

	private static boolean isActivated(Bundle bundle) {
		return bundle != null && (bundle.getState() & (Bundle.ACTIVE | Bundle.STOPPING)) != 0;
	}

	/**
	 * The constructor.
	 */
	protected RegistryReader() {
	}
	/**
	 * This method extracts description as a sub-element of the given element.
	 *
	 * @return description string if defined, or empty string if not.
	 */
	protected String getDescription(IConfigurationElement config) {
		IConfigurationElement[] children = config.getChildren(TAG_DESCRIPTION);
		if (children.length >= 1) {
			return children[0].getValue();
		}
		return ""; //$NON-NLS-1$
	}
	/**
	 * Logs the error in the workbench log using the provided text and the
	 * information in the configuration element.
	 */
	protected void logError(IConfigurationElement element, String text) {
		IExtension extension = element.getDeclaringExtension();
		StringBuilder buf = new StringBuilder();
		buf.append("Plugin " + extension.getContributor().getName() + ", extension " + extension.getExtensionPointUniqueIdentifier()); //$NON-NLS-2$//$NON-NLS-1$
		buf.append("\n" + text); //$NON-NLS-1$
		TeamUIPlugin.log(IStatus.ERROR, buf.toString(), null);
	}
	/**
	 * Logs a very common registry error when a required attribute is missing.
	 */
	protected void logMissingAttribute(IConfigurationElement element, String attributeName) {
		logError(element, "Required attribute '" + attributeName + "' not defined"); //$NON-NLS-2$//$NON-NLS-1$
	}

	/**
	 * Logs a very common registry error when a required child is missing.
	 */
	protected void logMissingElement(IConfigurationElement element, String elementName) {
		logError(element, "Required sub element '" + elementName + "' not defined"); //$NON-NLS-2$//$NON-NLS-1$
	}

	/**
	 * Logs a registry error when the configuration element is unknown.
	 */
	protected void logUnknownElement(IConfigurationElement element) {
		logError(element, "Unknown extension tag found: " + element.getName()); //$NON-NLS-1$
	}
	/**
	 * Apply a reproducible order to the list of extensions provided, such that
	 * the order will not change as extensions are added or removed.
	 */
	protected IExtension[] orderExtensions(IExtension[] extensions) {
		// By default, the order is based on plugin id sorted
		// in ascending order. The order for a plugin providing
		// more than one extension for an extension point is
		// dependent in the order listed in the XML file.
		Sorter sorter = new Sorter() {
			@Override
			public boolean compare(Object extension1, Object extension2) {
				String s1 = ((IExtension) extension1).getContributor().getName();
				String s2 = ((IExtension) extension2).getContributor().getName();
				//Return true if elementTwo is 'greater than' elementOne
				return s2.compareToIgnoreCase(s1) > 0;
			}
		};

		Object[] sorted = sorter.sort(extensions);
		IExtension[] sortedExtension = new IExtension[sorted.length];
		System.arraycopy(sorted, 0, sortedExtension, 0, sorted.length);
		return sortedExtension;
	}
	/**
	 * Implement this method to read element's attributes. If children should
	 * also be read, then implementor is responsible for calling <code>readElementChildren</code>.
	 * Implementor is also responsible for logging missing attributes.
	 *
	 * @return true if element was recognized, false if not.
	 */
	protected abstract boolean readElement(IConfigurationElement element);
	/**
	 * Read the element's children. This is called by the subclass' readElement
	 * method when it wants to read the children of the element.
	 */
	protected void readElementChildren(IConfigurationElement element) {
		readElements(element.getChildren());
	}
	/**
	 * Read each element one at a time by calling the subclass implementation
	 * of <code>readElement</code>.
	 *
	 * Logs an error if the element was not recognized.
	 */
	protected void readElements(IConfigurationElement[] elements) {
		for (int i = 0; i < elements.length; i++) {
			if (!readElement(elements[i]))
				logUnknownElement(elements[i]);
		}
	}
	/**
	 * Read one extension by looping through its configuration elements.
	 */
	protected void readExtension(IExtension extension) {
		readElements(extension.getConfigurationElements());
	}
	/**
	 * Start the registry reading process using the supplied plugin ID and
	 * extension point.
	 * @param registry the registry
	 * @param pluginId the plug-in id
	 * @param extensionPoint the extension point
	 */
	public void readRegistry(IExtensionRegistry registry, String pluginId, String extensionPoint) {
		String pointId = pluginId + "-" + extensionPoint; //$NON-NLS-1$
		IExtension[] extensions = extensionPoints.get(pointId);
		if (extensions == null) {
			IExtensionPoint point = registry.getExtensionPoint(pluginId, extensionPoint);
			if (point == null)
				return;
			extensions = point.getExtensions();
			extensionPoints.put(pointId, extensions);
		}
		for (int i = 0; i < extensions.length; i++)
			readExtension(extensions[i]);
	}
}
