/*******************************************************************************
 * Copyright (c) 2000, 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.core.internal.filebuffers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;

import org.eclipse.core.filebuffers.IAnnotationModelFactory;
import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
import org.eclipse.core.filebuffers.LocationKind;


/**
 * This registry manages sharable document factories and setup
 * participants that are specified in <code>plugin.xml</code>.
 */
public class ExtensionsRegistry {

	/**
	 * Adapts {@link IContentType} with the ability to check equality. This allows to use them in a
	 * collection.
	 */
	private static class ContentTypeAdapter {

		/** The adapted content type. */
		private IContentType fContentType;

		/**
		 * Creates a new content type adapter for the
		 * given content type.
		 *
		 * @param contentType the content type to be adapted
		 */
		public ContentTypeAdapter(IContentType  contentType) {
			Assert.isNotNull(contentType);
			fContentType= contentType;
		}

		/**
		 * Return the id of the adapted content type.
		 *
		 * @return the id
		 */
		public String getId() {
			return fContentType.getId();
		}

		@Override
		public boolean equals(Object obj) {
			return obj instanceof ContentTypeAdapter && fContentType.getId().equals(((ContentTypeAdapter)obj).getId());
		}

		@Override
		public int hashCode() {
			return fContentType.getId().hashCode();
		}
	}

	protected static final String WILDCARD= "*"; //$NON-NLS-1$

	/** The mapping between file attributes and configuration elements describing document factories. */
	private Map<Object, Set<IConfigurationElement>> fFactoryDescriptors= new HashMap<>();
	/** The mapping between configuration elements for document factories and instantiated document factories. */
	private Map<IConfigurationElement, Object> fFactories= new HashMap<>();
	/** The mapping between file attributes and configuration elements describing document setup participants. */
	private Map<Object, Set<IConfigurationElement>> fSetupParticipantDescriptors= new HashMap<>();
	/** The mapping between configuration elements for setup participants and instantiated setup participants. */
	private Map<IConfigurationElement, Object> fSetupParticipants= new HashMap<>();
	/** The mapping between file attributes and configuration elements describing annotation model factories. */
	private Map<Object, Set<IConfigurationElement>> fAnnotationModelFactoryDescriptors= new HashMap<>();
	/** The mapping between configuration elements for annotation model factories */
	private Map<IConfigurationElement, Object> fAnnotationModelFactories= new HashMap<>();
	/** The content type manager. */
	protected IContentTypeManager fContentTypeManager= Platform.getContentTypeManager();


	/**
	 * Creates a new document factory registry and initializes it with the information
	 * found in the plug-in registry.
	 */
	public ExtensionsRegistry() {
		initialize("documentCreation", "contentTypeId", true,  fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("documentCreation", "fileNames", false, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("documentCreation", "extensions",  false, fFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("documentSetup", "contentTypeId", true, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("documentSetup", "fileNames", false, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("documentSetup", "extensions", false, fSetupParticipantDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("annotationModelCreation", "contentTypeId", true, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("annotationModelCreation", "fileNames", false, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$
		initialize("annotationModelCreation", "extensions", false, fAnnotationModelFactoryDescriptors); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/**
	 * Reads the comma-separated value from the given configuration element for the given attribute name and remembers
	 * the configuration element in the given map under the individual tokens of the attribute value.
	 *
	 * @param attributeName the name of the attribute
	 * @param element the configuration element
	 * @param map the map which remembers the configuration element
	 */
	private void read(String attributeName, IConfigurationElement element, Map<Object, Set<IConfigurationElement>> map) {
		String value= element.getAttribute(attributeName);
		if (value != null) {
			StringTokenizer tokenizer= new StringTokenizer(value, ","); //$NON-NLS-1$
			while (tokenizer.hasMoreTokens()) {
				String token= tokenizer.nextToken().trim();

				Set<IConfigurationElement> s= map.get(token);
				if (s == null) {
					s= new HashSet<>();
					map.put(token, s);
				}
				s.add(element);
			}
		}
	}

	/**
	 * Reads the value from the given configuration element for the given attribute name and remembers
	 * the configuration element in the given map under the individual content type of the attribute value.
	 *
	 * @param attributeName the name of the attribute
	 * @param element the configuration element
	 * @param map the map which remembers the configuration element
	 */
	private void readContentType(String attributeName, IConfigurationElement element, Map<Object, Set<IConfigurationElement>> map) {
		String value= element.getAttribute(attributeName);
		if (value != null) {
			IContentType contentType= fContentTypeManager.getContentType(value);
			if (contentType == null) {
				log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, NLSUtility.format(FileBuffersMessages.ExtensionsRegistry_error_contentTypeDoesNotExist, value), null));
				return;
			}
			ContentTypeAdapter adapter= new ContentTypeAdapter(contentType);
			Set<IConfigurationElement> s= map.get(adapter);
			if (s == null) {
				s= new HashSet<>();
				map.put(adapter, s);
			}
			s.add(element);
		}
	}

	/**
	 * Adds an entry to the log of this plug-in for the given status
	 * @param status the status to log
	 */
	private void log(IStatus status) {
		ILog log= FileBuffersPlugin.getDefault().getLog();
		log.log(status);
	}

	/**
	 * Initializes this registry. It retrieves all implementers of the given
	 * extension point and remembers those implementers based on the
	 * file name extensions in the given map.
	 *
	 * @param extensionPointName the name of the extension point
	 * @param childElementName the name of the child elements
	 * @param isContentTypeId the child element is a content type id
	 * @param descriptors the map to be filled
	 */
	private void initialize(String extensionPointName, String childElementName, boolean isContentTypeId, Map<Object, Set<IConfigurationElement>> descriptors) {

		IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(FileBuffersPlugin.PLUGIN_ID, extensionPointName);
		if (extensionPoint == null) {
			log(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 0, NLSUtility.format(FileBuffersMessages.ExtensionsRegistry_error_extensionPointNotFound, extensionPointName), null));
			return;
		}

		IConfigurationElement[] elements= extensionPoint.getConfigurationElements();
		for (int i= 0; i < elements.length; i++) {
			if (isContentTypeId)
				readContentType(childElementName, elements[i], descriptors);
			else
				read(childElementName, elements[i], descriptors);
		}
	}

	/**
	 * Returns the executable extension for the given configuration element.
	 * If there is no instantiated extension remembered for this
	 * element, a new extension is created and put into the cache if it is of the requested type.
	 *
	 * @param entry the configuration element
	 * @param extensions the map of instantiated extensions
	 * @param extensionType the requested result type
	 * @return the executable extension for the given configuration element.
	 */
	@SuppressWarnings("unchecked")
	private <T> T getExtension(IConfigurationElement entry, Map<IConfigurationElement, Object> extensions, Class<T> extensionType) {
		T extension= (T) extensions.get(entry);
		if (extension != null)
			return extension;

		try {
			extension= (T) entry.createExecutableExtension("class"); //$NON-NLS-1$
		} catch (CoreException x) {
			log(x.getStatus());
		}

		if (extensionType.isInstance(extension)) {
			extensions.put(entry, extension);
			return extension;
		}

		return null;
	}

	/**
	 * Returns the first enumerated element of the given set.
	 *
	 * @param set the set from which to choose
	 * @return the selected configuration element
	 */
	private IConfigurationElement selectConfigurationElement(Set<IConfigurationElement> set) {
		if (set != null && !set.isEmpty()) {
			Iterator<IConfigurationElement> e= set.iterator();
			return e.next();
		}
		return null;
	}

	/**
	 * Returns a sharable document factory for the given file name or file extension.
	 *
	 * @param nameOrExtension the name or extension to be used for lookup
	 * @return the sharable document factory or <code>null</code>
	 * @deprecated As of 3.5
	 */
	@Deprecated
	protected org.eclipse.core.filebuffers.IDocumentFactory getDocumentFactory(String nameOrExtension) {
		Set<IConfigurationElement> set= fFactoryDescriptors.get(nameOrExtension);
		if (set != null) {
			IConfigurationElement entry= selectConfigurationElement(set);
			return getExtension(entry, fFactories, org.eclipse.core.filebuffers.IDocumentFactory.class);
		}
		return null;
	}

	/**
	 * Returns a sharable document factory for the given content types.
	 *
	 * @param contentTypes the content types used to find the factory
	 * @return the sharable document factory or <code>null</code>
	 * @deprecated As of 3.5
	 */
	@Deprecated
	protected org.eclipse.core.filebuffers.IDocumentFactory doGetDocumentFactory(IContentType[] contentTypes) {
		Set<IConfigurationElement> set= null;
		int i= 0;
		while (i < contentTypes.length && set == null) {
			set= fFactoryDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
		}

		if (set != null) {
			IConfigurationElement entry= selectConfigurationElement(set);
			return getExtension(entry, fFactories, org.eclipse.core.filebuffers.IDocumentFactory.class);
		}
		return null;
	}

	/**
	 * Returns a sharable document factory for the given content types. This method considers the
	 * base content types of the given set of content types.
	 *
	 * @param contentTypes the content types used to find the factory
	 * @return the sharable document factory or <code>null</code>
	 * @deprecated As of 3.5
	 */
	@Deprecated
	protected org.eclipse.core.filebuffers.IDocumentFactory getDocumentFactory(IContentType[] contentTypes) {
		org.eclipse.core.filebuffers.IDocumentFactory factory= doGetDocumentFactory(contentTypes);
		while (factory == null) {
			contentTypes= computeBaseContentTypes(contentTypes);
			if (contentTypes == null)
				break;
			factory= doGetDocumentFactory(contentTypes);
		}
		return factory;
	}

	/**
	 * Returns the set of setup participants for the given file name or extension.
	 *
	 * @param nameOrExtension the name or extension to be used for lookup
	 * @return the sharable set of document setup participants
	 */
	protected List<IDocumentSetupParticipant> getDocumentSetupParticipants(String nameOrExtension) {
		Set<IConfigurationElement> set= fSetupParticipantDescriptors.get(nameOrExtension);
		if (set == null)
			return null;

		List<IDocumentSetupParticipant> participants= new ArrayList<>();
		Iterator<IConfigurationElement> e= set.iterator();
		while (e.hasNext()) {
			IConfigurationElement entry= e.next();
			IDocumentSetupParticipant participant= getExtension(entry, fSetupParticipants, IDocumentSetupParticipant.class);
			if (participant != null)
				participants.add(participant);
		}

		return participants;
	}

	/**
	 * Returns the set of setup participants for the given content types.
	 *
	 * @param contentTypes the contentTypes to be used for lookup
	 * @return the sharable set of document setup participants
	 */
	private List<IDocumentSetupParticipant> doGetDocumentSetupParticipants(IContentType[] contentTypes) {
		Set<IConfigurationElement> resultSet= new HashSet<>();
		int i= 0;
		while (i < contentTypes.length) {
			Set<IConfigurationElement> set= fSetupParticipantDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
			if (set != null)
				resultSet.addAll(set);
		}

		List<IDocumentSetupParticipant> participants= new ArrayList<>();
		Iterator<IConfigurationElement> e= resultSet.iterator();
		while (e.hasNext()) {
			IConfigurationElement entry= e.next();
			IDocumentSetupParticipant participant= getExtension(entry, fSetupParticipants, IDocumentSetupParticipant.class);
			if (participant != null)
				participants.add(participant);
		}

		return participants.isEmpty() ? null : participants;
	}

	/**
	 * Returns the set of setup participants for the given content types. This
	 * method considers the base content types of the given set of content
	 * types.
	 *
	 * @param contentTypes the contentTypes to be used for lookup
	 * @return the sharable set of document setup participants
	 */
	protected List<IDocumentSetupParticipant> getDocumentSetupParticipants(IContentType[] contentTypes) {
		List<IDocumentSetupParticipant> participants= doGetDocumentSetupParticipants(contentTypes);
		while (participants == null) {
			contentTypes= computeBaseContentTypes(contentTypes);
			if (contentTypes == null)
				break;
			participants= doGetDocumentSetupParticipants(contentTypes);
		}
		return participants;
	}

	/**
	 * Returns a sharable annotation model factory for the given content types.
	 *
	 * @param contentTypes the content types used to find the factory
	 * @return the sharable annotation model factory or <code>null</code>
	 */
	private IAnnotationModelFactory doGetAnnotationModelFactory(IContentType[] contentTypes) {
		Set<IConfigurationElement> set= null;
		int i= 0;
		while (i < contentTypes.length && set == null) {
			set= fAnnotationModelFactoryDescriptors.get(new ContentTypeAdapter(contentTypes[i++]));
		}

		if (set != null) {
			IConfigurationElement entry= selectConfigurationElement(set);
			return getExtension(entry, fAnnotationModelFactories, IAnnotationModelFactory.class);
		}
		return null;
	}

	/**
	 * Returns a sharable annotation model factory for the given content types.
	 * This method considers the base content types of the given set of content
	 * types.
	 *
	 * @param contentTypes the content types used to find the factory
	 * @return the sharable annotation model factory or <code>null</code>
	 */
	protected IAnnotationModelFactory getAnnotationModelFactory(IContentType[] contentTypes) {
		IAnnotationModelFactory factory= doGetAnnotationModelFactory(contentTypes);
		while (factory == null) {
			contentTypes= computeBaseContentTypes(contentTypes);
			if (contentTypes == null)
				break;
			factory= doGetAnnotationModelFactory(contentTypes);
		}
		return factory;
	}

	/**
	 * Returns a sharable annotation model factory for the given file name or file extension.
	 *
	 * @param extension the name or extension to be used for lookup
	 * @return the sharable document factory or <code>null</code>
	 */
	protected IAnnotationModelFactory getAnnotationModelFactory(String extension) {
		Set<IConfigurationElement> set= fAnnotationModelFactoryDescriptors.get(extension);
		if (set != null) {
			IConfigurationElement entry= selectConfigurationElement(set);
			return getExtension(entry, fAnnotationModelFactories, IAnnotationModelFactory.class);
		}
		return null;
	}

	/**
	 * Returns the set of content types for the given location.
	 *
	 * @param location the location for which to look up the content types
	 * @param locationKind the kind of the given location
	 * @return the set of content types for the location
	 * @since 3.3
	 */
	protected IContentType[] findContentTypes(IPath location, LocationKind locationKind) {
		Assert.isLegal(locationKind != LocationKind.IFILE);
		return fContentTypeManager.findContentTypesFor(location.lastSegment());
	}

	/**
	 * Returns the set of direct base content types for the given set of content
	 * types. Returns <code>null</code> if non of the given content types has
	 * a direct base content type.
	 *
	 * @param contentTypes the content types
	 * @return the set of direct base content types
	 */
	private IContentType[] computeBaseContentTypes(IContentType[] contentTypes) {
		List<IContentType> baseTypes= new ArrayList<>();
		for (int i= 0; i < contentTypes.length; i++) {
			IContentType baseType= contentTypes[i].getBaseType();
			if (baseType != null)
				baseTypes.add(baseType);
		}

		IContentType[] result= null;
		int size= baseTypes.size();
		if (size > 0) {
			result= new IContentType[size];
			baseTypes.toArray(result);
		}
		return result;
	}

	/**
	 * Returns the sharable document factory for the given location.
	 *
	 * @param location the location for which to looked up the factory
	 * @param locationKind the kind of the given location
	 * @return the sharable document factory
	 * @since 3.3
	 * @deprecated As of 3.5
	 */
	@Deprecated
	public org.eclipse.core.filebuffers.IDocumentFactory getDocumentFactory(IPath location, LocationKind locationKind) {
		org.eclipse.core.filebuffers.IDocumentFactory factory= getDocumentFactory(findContentTypes(location, locationKind));
		if (factory == null)
			factory= getDocumentFactory(location.lastSegment());
		if (factory == null)
			factory= getDocumentFactory(location.getFileExtension());
		if (factory == null)
			factory= getDocumentFactory(WILDCARD);
		return factory;
	}

	/**
	 * Returns the sharable set of document setup participants for the given location.
	 *
	 * @param location the location for which to look up the setup participants
	 * @param locationKind the kind of the given location
	 * @return the sharable set of document setup participants
	 * @since 3.3
	 */
	public IDocumentSetupParticipant[] getDocumentSetupParticipants(IPath location, LocationKind locationKind) {
		Set<IDocumentSetupParticipant> participants= new HashSet<>();

		List<IDocumentSetupParticipant> p= getDocumentSetupParticipants(findContentTypes(location, locationKind));
		if (p != null)
			participants.addAll(p);

		p= getDocumentSetupParticipants(location.lastSegment());
		if (p != null)
			participants.addAll(p);

		p= getDocumentSetupParticipants(location.getFileExtension());
		if (p != null)
			participants.addAll(p);

		p= getDocumentSetupParticipants(WILDCARD);
		if (p != null)
			participants.addAll(p);

		IDocumentSetupParticipant[] result= new IDocumentSetupParticipant[participants.size()];
		participants.toArray(result);
		return result;
	}

	/**
	 * Returns the sharable annotation model factory for the given location.
	 *
	 * @param location the location for which to look up the factory
	 * @param locationKind the kind of the given location
	 * @return the sharable annotation model factory
	 * @since 3.3
	 */
	public IAnnotationModelFactory getAnnotationModelFactory(IPath location, LocationKind locationKind) {
		IAnnotationModelFactory factory= getAnnotationModelFactory(findContentTypes(location, locationKind));
		if (factory == null)
			factory= getAnnotationModelFactory(location.lastSegment());
		if (factory == null)
			factory= getAnnotationModelFactory(location.getFileExtension());
		if (factory == null)
			factory= getAnnotationModelFactory(WILDCARD);
		return factory;
	}

}
