/*********************************************************************
* Copyright (c) 2005, 2019 SAP SE
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
*    SAP SE - initial API, implementation and documentation
*    mwenz - Bug 352709 - invalid image provider id crashes diagram editor
*    fvelasco - Bug 323349 - Enable external invocation of features
*    fvelasco - Bug 396247 - ImageDescriptor changes
*    pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.graphiti.ui.internal.platform;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.dt.IDiagramType;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.internal.util.T;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.ui.editor.IDiagramContainerUI;
import org.eclipse.graphiti.ui.internal.editor.DiagramEditorDummy;
import org.eclipse.graphiti.ui.internal.util.ui.print.IDiagramsExporter;
import org.eclipse.graphiti.ui.platform.IImageProvider;
import org.eclipse.graphiti.ui.platform.PlatformImageProvider;
import org.eclipse.graphiti.ui.services.IExtensionManager;

/**
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
public class ExtensionManager implements IExtensionManager {

	private static ExtensionManager singleton;

	private static String EP_DIAGRAM_TYPES = "org.eclipse.graphiti.ui.diagramTypes"; //$NON-NLS-1$

	private static String EP_IMAGE_PROVIDERS = "org.eclipse.graphiti.ui.imageProviders"; //$NON-NLS-1$

	private static String EP_DIAGRAM_TYPE_PROVIDERS = "org.eclipse.graphiti.ui.diagramTypeProviders"; //$NON-NLS-1$

	private static String EP_DIAGRAM_EXPORTERS = "org.eclipse.graphiti.ui.diagramExporters"; //$NON-NLS-1$

	private static final String EP_CHILD_NODE_DIAGRAM_EXPORTER = "diagramexporter"; //$NON-NLS-1$

	private static final String EP_CHILD_NODE_IMAGE_PROVIDER = "imageProvider"; //$NON-NLS-1$

	private static final String EP_CHILD_NODE_DIAGRAM_TYPE = "diagramType"; //$NON-NLS-1$

	private static final String EP_CHILD_NODE_DIAGRAM_TYPE_PROVIDER = "diagramTypeProvider"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_ID = "id"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_TYPE = "type"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_ENABLEUI = "enableScaling"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_DESCRIPTION = "description"; //$NON-NLS-1$

	private static final String EP_ATTRIBUTE_CONTEXT = "context"; //$NON-NLS-1$

	private IDiagramType diagramTypes[] = null;

	private IImageProvider imageProviders[] = null;

	private IImageProvider platformImageProvider = null;

	private Map<String, Set<IImageProvider>> dtp2imageProvider = null;

	/**
	 * 
	 */
	private ExtensionManager() {
		super();
		dtp2imageProvider = new HashMap<String, Set<IImageProvider>>();
		searchForExtensions();
	}

	public static ExtensionManager getSingleton() {
		if (singleton == null) {
			singleton = new ExtensionManager();
		}
		return singleton;
	}

	public String[] getDiagramTypeProviderIds(String diagramTypeId) {
		String ret[] = new String[0];
		if (diagramTypeId == null) {
			return ret;
		}
		List<String> retList = new ArrayList<String>();

		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();

		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPE_PROVIDERS);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
				if (extensionId != null) {
					// read references to diagram types
					IConfigurationElement[] children = element.getChildren();
					for (int k = 0; k < children.length; k++) {
						IConfigurationElement childElement = children[k];
						String childName = childElement.getName();
						String childExtensionId = childElement.getAttribute(EP_ATTRIBUTE_ID);
						if (childName != null && childExtensionId != null) {
							if (EP_CHILD_NODE_DIAGRAM_TYPE.equals(childName)) {
								String typeId = getDiagramTypeIdForDiagramTypeProviderId(childExtensionId);
								if (diagramTypeId.equals(typeId)) {
									retList.add(extensionId);
									break;
								}
							}
						}
					}
				}
			}
		}

		ret = retList.toArray(ret);
		return ret;
	}

	public Map<String, Boolean> getDiagramExporterTypes() {
		Map<String, Boolean> ret = new HashMap<String, Boolean>();
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_EXPORTERS);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String name = element.getName();
				String type = element.getAttribute(EP_ATTRIBUTE_TYPE);
				if (name != null && type != null) {
					if (EP_CHILD_NODE_DIAGRAM_EXPORTER.equals(name)) {
						String enableScaling = element.getAttribute(EP_ATTRIBUTE_ENABLEUI);
						ret.put(type, Boolean.valueOf(enableScaling));
						break;
					}
				}
			}
		}
		return ret;
	}

	public IDiagramsExporter getDiagramExporterForType(String type) {
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_EXPORTERS);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String name = element.getName();
				String currType = element.getAttribute(EP_ATTRIBUTE_TYPE);
				if (name != null && type != null) {
					if (EP_CHILD_NODE_DIAGRAM_EXPORTER.equals(name) && type.equals(currType)) {
						try {
							Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
							if (executableExtension instanceof IDiagramsExporter) {
								return (IDiagramsExporter) executableExtension;
							}
						} catch (CoreException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}

		return null;
	}

	private void searchForExtensions() {

		// read and store all diagram types which are registered with the
		// extension point
		List<IDiagramType> diagramTypeList = createDiagramTypes();
		diagramTypes = diagramTypeList.toArray(new IDiagramType[0]);

		imageProviders = new IImageProvider[0];

		// load image providers from the framework
		platformImageProvider = loadImageProvider(PlatformImageProvider.ID);
	}

	public IDiagramTypeProvider createDiagramTypeProvider(String providerId) {
		IDiagramTypeProvider diagramTypeProvider = null;

		if (providerId == null) {
			return diagramTypeProvider;
		}
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();

		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPE_PROVIDERS);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
				if (extensionId != null && extensionId.equals(providerId)) {
					String name = element.getAttribute(EP_ATTRIBUTE_NAME);
					String description = element.getAttribute(EP_ATTRIBUTE_DESCRIPTION);
					if (description == null) {
						description = ""; //$NON-NLS-1$
					}
					String context = element.getAttribute(EP_ATTRIBUTE_CONTEXT);
					if (context == null) {
						context = IDiagramContainerUI.DIAGRAM_CONTEXT_ID;
					}
					if (name != null) {
						// read direct references to image extensions and try to
						// instantiate image provider
						IConfigurationElement[] children = element.getChildren();
						for (int k = 0; k < children.length; k++) {
							IConfigurationElement childElement = children[k];
							String childName = childElement.getName();
							String childExtensionId = childElement.getAttribute(EP_ATTRIBUTE_ID);
							if (childName != null && childExtensionId != null) {
								if (EP_CHILD_NODE_IMAGE_PROVIDER.equals(childName)) {
									IImageProvider imageProvider = loadImageProvider(childExtensionId);
									if (imageProvider == null) {
										IllegalArgumentException e = new IllegalArgumentException("A Graphiti image provider with id '" //$NON-NLS-1$
												+ childExtensionId + "' could not be found"); //$NON-NLS-1$
										T.racer().error("Error while creating the children for '" + providerId + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
									} else {
										registerImageProviderForDiagramTypeProvider(providerId, imageProvider);
									}
								}
							}
						}
						try {
							Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
							if (executableExtension instanceof IDiagramTypeProvider) {
								diagramTypeProvider = (IDiagramTypeProvider) executableExtension;
								diagramTypeProvider.setProviderId(extensionId);
								diagramTypeProvider.setContextId(context);
								// TODO later store also name and description -
								// is only necessary if this information
								// are shown in the UI
							}
						} catch (CoreException e) {
							// $JL-EXC$
							T.racer().error("Unable to create DiagramTypeProvider class", e);
						}
					}
				}
			}
		}

		IExtensionPoint imageProviderExtensionPoint = extensionRegistry.getExtensionPoint(EP_IMAGE_PROVIDERS);
		// read image providers that point back to this diagramTypeProvider
		for (IExtension extension : imageProviderExtensionPoint.getExtensions()) {
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String imageProviderId = element.getAttribute(EP_ATTRIBUTE_ID);

				IConfigurationElement[] children = element.getChildren(EP_CHILD_NODE_DIAGRAM_TYPE_PROVIDER);

				for (IConfigurationElement child : children) {
					String referredDiagramTypeProviderId = child.getAttribute(EP_ATTRIBUTE_ID);
					if (providerId.equals(referredDiagramTypeProviderId)) {
						IImageProvider imageProvider = loadImageProvider(imageProviderId);
						registerImageProviderForDiagramTypeProvider(providerId, imageProvider);
						break;
					}
				}
			}
		}

		return diagramTypeProvider;
	}

	public IImageProvider getPlatformImageProvider() {
		return platformImageProvider;
	}

	public Collection<IImageProvider> getImageProvidersForDiagramTypeProviderId(String providerId) {
		Collection<IImageProvider> providers = dtp2imageProvider.get(providerId);
		if (providers == null)
			return Collections.singleton(platformImageProvider);
		else
			return providers;
	}

	public IDiagramType[] getDiagramTypes() {
		return diagramTypes;
	}

	private String getDiagramTypeIdForDiagramTypeProviderId(String providerId) {
		if (providerId != null) {
			IDiagramType diagramTypes[] = getDiagramTypes();
			for (int i = 0; i < diagramTypes.length; i++) {
				IDiagramType diagramType = diagramTypes[i];
				if (providerId.equals(diagramType.getProviderId())) {
					return diagramType.getId();
				}
			}
		}
		return null;
	}

	private IImageProvider loadImageProvider(String imageProviderId) {

		// check whether the image provider is already loaded
		for (int i = 0; i < imageProviders.length; i++) {
			IImageProvider provider = imageProviders[i];
			if (imageProviderId.equals(provider.getProviderId())) {
				return provider;
			}
		}
		IImageProvider newProvider = createImageProvider(imageProviderId);
		if (newProvider != null) {

			// extend current list of image providers
			IImageProvider imageProvidersDest[] = new IImageProvider[imageProviders.length + 1];
			System.arraycopy(imageProviders, 0, imageProvidersDest, 0, imageProviders.length);
			imageProvidersDest[imageProviders.length] = newProvider;
			imageProviders = imageProvidersDest;

			return newProvider;
		}

		return null;
	}

	private List<IDiagramType> createDiagramTypes() {

		List<IDiagramType> ret = new ArrayList<IDiagramType>();

		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();

		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPES);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
				String typeId = element.getAttribute(EP_ATTRIBUTE_TYPE);
				String typeName = element.getAttribute(EP_ATTRIBUTE_NAME);
				String typeDescription = element.getAttribute(EP_ATTRIBUTE_DESCRIPTION);
				if (typeDescription == null) {
					typeDescription = ""; //$NON-NLS-1$
				}
				if (extensionId != null && typeId != null && typeName != null) {
					IDiagramType diagramType = new DiagramTypeImpl(typeId, typeName, typeDescription);
					diagramType.setProviderId(extensionId);
					ret.add(diagramType);
				}
			}
		}
		return ret;
	}

	private IImageProvider createImageProvider(String providerId) {

		if (providerId == null) {
			return null;
		}
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();

		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_IMAGE_PROVIDERS);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			IConfigurationElement[] configurationElements = extension.getConfigurationElements();
			for (int j = 0; j < configurationElements.length; j++) {
				IConfigurationElement element = configurationElements[j];
				String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
				if (providerId.equals(extensionId)) {
					try {
						Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
						if (executableExtension instanceof IImageProvider) {
							IContributor contributor = extension.getContributor();
							if (contributor != null) {
								String pluginId = contributor.getName();
								if (pluginId != null) {
									IImageProvider imageProvider = (IImageProvider) executableExtension;
									imageProvider.setProviderId(extensionId);
									imageProvider.setPluginId(pluginId);
									return imageProvider;
								}
							}
						}
					} catch (CoreException e) {
						// $JL-EXC$
						e.printStackTrace();
					}
				}
			}
		}
		return null;
	}

	private void registerImageProviderForDiagramTypeProvider(String providerId, IImageProvider imageProvider) {
		Set<IImageProvider> providers = dtp2imageProvider.get(providerId);
		if (providers == null) {
			providers = new HashSet<IImageProvider>();
			dtp2imageProvider.put(providerId, providers);
			providers.add(platformImageProvider);
		}

		providers.add(imageProvider);
	}

	public IFeatureProvider createFeatureProvider(Diagram diagram) {
		Assert.isNotNull(diagram);
		String providerId = getDiagramTypeProviderId(diagram.getDiagramTypeId());
		if (providerId != null) {
			IDiagramTypeProvider dtp = createDiagramTypeProvider(diagram, providerId);
			return dtp.getFeatureProvider();
		}
		return null;
	}

	public IDiagramTypeProvider createDiagramTypeProvider(Diagram diagram, String providerId) {
		Assert.isNotNull(diagram);
		IDiagramTypeProvider dtp = createDiagramTypeProvider(providerId);
		if (dtp != null) {
			TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(diagram);
			DiagramEditorDummy diagramEditor = new DiagramEditorDummy(dtp, editingDomain);
			dtp.init(diagram, diagramEditor.getDiagramBehavior());
		}
		return dtp;
	}

	public String getDiagramTypeProviderId(String diagramTypeId) {
		String diagramTypeProviders[] = getDiagramTypeProviderIds(diagramTypeId);
		if (diagramTypeProviders != null && diagramTypeProviders.length > 0) {
			return diagramTypeProviders[0];
		}
		return null;
	}

}
