/*
 * Copyright (c) 2012, 2018 CEA, Obeo, and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   Kenn Hussey (CEA) - initial API and implementation
 *   Kenn Hussey (CEA) - 389542, 399544, 425846, 418466, 429352
 *   Mikael Barbero (Obeo) - 414572
 *   Christian W. Damus (CEA) - 414572, 401682
 *   Kenn Hussey - 526217, 539580, 535301
 */
package org.eclipse.uml2.uml.resources.util;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.ContentHandler;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLContentHandlerImpl;
import org.eclipse.uml2.types.TypesPackage;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.profile.standard.StandardPackage;
import org.eclipse.uml2.uml.resource.CMOF2UMLResource;
import org.eclipse.uml2.uml.resource.UML212UMLResource;
import org.eclipse.uml2.uml.resource.UML22UMLResource;
import org.eclipse.uml2.uml.resource.UML302UMLResource;
import org.eclipse.uml2.uml.resource.UML402UMLResource;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.resource.XMI2UMLResource;
import org.eclipse.uml2.uml.resources.ResourcesPlugin;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * @since 4.0
 */
public class UMLResourcesUtil
		extends UMLUtil {

	private static final ContentHandler XMI_CONTENT_HANDLER = new XMLContentHandlerImpl.XMI();

	private static final ContentHandler UML2_1_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UML22UMLResource.UML2_CONTENT_TYPE_IDENTIFIER,
		new String[]{UML22UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		UML22UMLResource.UML2_METAMODEL_NS_URI, null);

	private static final ContentHandler UML2_2_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UMLResource.UML_2_0_0_CONTENT_TYPE_IDENTIFIER,
		new String[]{UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND, UML2_UML_PACKAGE_2_0_NS_URI, null);

	private static final ContentHandler UML2_2_1_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UMLResource.UML_2_1_0_CONTENT_TYPE_IDENTIFIER,
		new String[]{UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		UML212UMLResource.UML_METAMODEL_NS_URI, null);

	private static final ContentHandler UML2_3_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UMLResource.UML_3_0_0_CONTENT_TYPE_IDENTIFIER,
		new String[]{UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		UML302UMLResource.UML_METAMODEL_NS_URI, null);

	private static final ContentHandler UML2_4_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UMLResource.UML_4_0_0_CONTENT_TYPE_IDENTIFIER,
		new String[]{UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		UML402UMLResource.UML_METAMODEL_NS_URI, null);

	private static final ContentHandler UML2_5_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		UMLResource.UML_5_0_0_CONTENT_TYPE_IDENTIFIER,
		new String[]{UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND, UMLPackage.eNS_URI, null);

	private static final ContentHandler OMG_2_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_1_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_1_NS_URI, null);

	private static final ContentHandler OMG_2_1_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_1_1_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_1_1_NS_URI, null);

	private static final ContentHandler OMG_2_2_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_2_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_2_NS_URI, null);

	private static final ContentHandler OMG_2_4_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_4_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_4_NS_URI, null);

	private static final ContentHandler OMG_2_4_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_4_1_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_4_1_NS_URI, null);

	private static final ContentHandler OMG_2_5_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		XMI2UMLResource.UML_2_5_CONTENT_TYPE_IDENTIFIER,
		new String[]{XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		XMI2UMLResource.UML_METAMODEL_2_5_NS_URI, null);

	private static final ContentHandler CMOF_2_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		CMOF2UMLResource.CMOF_2_0_CONTENT_TYPE_IDENTIFIER, new String[]{
			CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		CMOF2UMLResource.CMOF_2_0_METAMODEL_NS_URI, null);

	private static final ContentHandler CMOF_2_4_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		CMOF2UMLResource.CMOF_2_4_CONTENT_TYPE_IDENTIFIER, new String[]{
			CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		CMOF2UMLResource.CMOF_2_4_METAMODEL_NS_URI, null);

	private static final ContentHandler CMOF_2_4_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		CMOF2UMLResource.CMOF_2_4_1_CONTENT_TYPE_IDENTIFIER, new String[]{
			CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		CMOF2UMLResource.CMOF_2_4_1_METAMODEL_NS_URI, null);

	private static final ContentHandler CMOF_2_5_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
		CMOF2UMLResource.CMOF_2_5_CONTENT_TYPE_IDENTIFIER, new String[]{
			CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
		RootXMLContentHandlerImpl.XMI_KIND,
		CMOF2UMLResource.CMOF_2_5_METAMODEL_NS_URI, null);

	/**
	 * Adds registrations to EMF's and UML2's global registries that enable
	 * working with UML models. To apply the same registrations only locally on
	 * a resource set (e.g., for isolation from other EMF-based code in the same
	 * class loader), use the {@link #initLocalRegistries(ResourceSet)} method,
	 * instead.
	 * 
	 * @see #initLocalRegistries(ResourceSet)
	 * 
	 * @since 5.0
	 */
	public static void initGlobalRegistries() {
		initPackageRegistry(EPackage.Registry.INSTANCE);
		initEPackageNsURIToProfileLocationMap(UMLPlugin
			.getEPackageNsURIToProfileLocationMap());
		initURIConverterURIMap(URIConverter.URI_MAP);
		initContentHandlerRegistry(ContentHandler.Registry.INSTANCE);
		initResourceFactoryRegistry(Resource.Factory.Registry.INSTANCE);
	}

	/**
	 * Adds registrations to a resource set's local registries that enable
	 * working with UML models in that resource set.
	 * 
	 * @see #initPackageRegistry(org.eclipse.emf.ecore.EPackage.Registry)
	 * @see #initResourceFactoryRegistry(org.eclipse.emf.ecore.resource.Resource.Factory.Registry)
	 * @see #initContentHandlerRegistry(org.eclipse.emf.ecore.resource.ContentHandler.Registry)
	 * @see #initURIConverterURIMap(Map)
	 * @see #initEPackageNsURIToProfileLocationMap(Map)
	 * 
	 * @since 5.0
	 */
	public static void initLocalRegistries(ResourceSet resourceSet) {
		initPackageRegistry(resourceSet.getPackageRegistry());

		// there is no local registry for this
		initEPackageNsURIToProfileLocationMap(UMLPlugin
			.getEPackageNsURIToProfileLocationMap());

		initURIConverterURIMap(resourceSet.getURIConverter().getURIMap());

		// there is no local registry for this
		initContentHandlerRegistry(ContentHandler.Registry.INSTANCE);

		initResourceFactoryRegistry(resourceSet.getResourceFactoryRegistry());
	}

	/**
	 * <p>
	 * Initializes the global registries and, if provided, the local registries
	 * for the specified resource set, with the registrations needed to work
	 * with UML2 resources in stand-alone mode (i.e., without Eclipse).
	 * </p>
	 * <p>
	 * <string>Note</string> that as of the 5.0 release, clients now have more
	 * fine-grained control over which registries (local or global) are
	 * initialized. Clients are encouraged to use these new APIs to ensure
	 * optimal behaviour and, where necessary, isolation from other code in the
	 * same class loader using the global registries.
	 * </p>
	 * 
	 * @param resourceSet
	 *            The resource set whose local registries to initialize, or
	 *            <code>null</code> to perform only global registrations.
	 * @return The resource set (or <code>null</code>).
	 * 
	 * @since 4.0
	 * 
	 * @see #initLocalRegistries(ResourceSet)
	 * @see #initGlobalRegistries()
	 */
	public static ResourceSet init(ResourceSet resourceSet) {
		initGlobalRegistries();
		return UMLUtil.init(resourceSet);
	}

	/**
	 * Adds packages required for working with UML models to the specified
	 * registry.
	 * 
	 * @param packageRegistry
	 *            a package registry, perhaps local to a resource set or perhaps
	 *            the global registry
	 * 
	 * @return the same {@code packageRegistry}
	 * 
	 * @since 5.0
	 */
	public static EPackage.Registry initPackageRegistry(
			EPackage.Registry packageRegistry) {
		packageRegistry.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);

		packageRegistry.put(UML2_TYPES_PACKAGE_4_0_NS_URI,
			TypesPackage.eINSTANCE);

		packageRegistry.put(TypesPackage.eNS_URI, TypesPackage.eINSTANCE);

		packageRegistry.put(UML2_UML_PACKAGE_2_0_NS_URI, UMLPackage.eINSTANCE);

		packageRegistry.put(UML212UMLResource.UML_METAMODEL_NS_URI,
			UMLPackage.eINSTANCE);

		packageRegistry.put(UML302UMLResource.UML_METAMODEL_NS_URI,
			UMLPackage.eINSTANCE);

		packageRegistry.put(UML402UMLResource.UML_METAMODEL_NS_URI,
			UMLPackage.eINSTANCE);

		packageRegistry.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);

		packageRegistry.put(UML212UMLResource.STANDARD_PROFILE_NS_URI,
			StandardPackage.eINSTANCE);

		packageRegistry.put(UML402UMLResource.STANDARD_L2_PROFILE_NS_URI,
			StandardPackage.eINSTANCE);
		packageRegistry.put(UML402UMLResource.STANDARD_L3_PROFILE_NS_URI,
			StandardPackage.eINSTANCE);

		packageRegistry.put(StandardPackage.eNS_URI, StandardPackage.eINSTANCE);

		return packageRegistry;
	}

	/**
	 * Adds resource factories required for working with UML models to the
	 * specified registry.
	 * 
	 * @param resourceFactoryRegistry
	 *            a resource-factory registry, perhaps local to a resource set
	 *            or perhaps the global registry
	 * 
	 * @return the same {@code resourceFactoryRegistry}
	 * 
	 * @since 5.0
	 */
	public static Resource.Factory.Registry initResourceFactoryRegistry(
			Resource.Factory.Registry resourceFactoryRegistry) {
		Map<String, Object> extensionToFactoryMap = resourceFactoryRegistry
			.getExtensionToFactoryMap();
		extensionToFactoryMap.put(UMLResource.FILE_EXTENSION,
			UMLResource.Factory.INSTANCE);

		Map<String, Object> contentTypeToFactoryMap = resourceFactoryRegistry
			.getContentTypeToFactoryMap();
		contentTypeToFactoryMap.put(UMLResource.UML_CONTENT_TYPE_IDENTIFIER,
			UMLResource.Factory.INSTANCE);

		return resourceFactoryRegistry;
	}

	/**
	 * Adds content-type handlers required for working with UML models to the
	 * specified registry.
	 * 
	 * @param contentHandlerRegistry
	 *            a content-type handler registry, perhaps local to a resource
	 *            set or perhaps the global registry
	 * 
	 * @return the same {@code contentHandlerRegistry}
	 * 
	 * @since 5.0
	 */
	public static ContentHandler.Registry initContentHandlerRegistry(
			ContentHandler.Registry contentHandlerRegistry) {
		List<ContentHandler> contentHandlers = contentHandlerRegistry
			.get(ContentHandler.Registry.LOW_PRIORITY);

		if (contentHandlers == null
			|| !contentHandlers.contains(XMI_CONTENT_HANDLER)) {

			contentHandlerRegistry.put(ContentHandler.Registry.LOW_PRIORITY,
				XMI_CONTENT_HANDLER);
		}

		contentHandlers = contentHandlerRegistry
			.get(ContentHandler.Registry.NORMAL_PRIORITY);

		if (contentHandlers == null) {
			contentHandlerRegistry.put(ContentHandler.Registry.NORMAL_PRIORITY,
				contentHandlers = new ArrayList<ContentHandler>());
		}

		if (!contentHandlers.contains(UML2_5_0_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_5_0_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(UML2_4_0_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_4_0_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(UML2_3_0_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_3_0_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(UML2_2_1_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_2_1_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(UML2_2_0_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_2_0_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(UML2_1_0_0_CONTENT_HANDLER)) {
			contentHandlers.add(UML2_1_0_0_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_5_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_5_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_4_1_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_4_1_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_4_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_4_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_2_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_2_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_1_1_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_1_1_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(OMG_2_1_CONTENT_HANDLER)) {
			contentHandlers.add(OMG_2_1_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(CMOF_2_5_CONTENT_HANDLER)) {
			contentHandlers.add(CMOF_2_5_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(CMOF_2_4_1_CONTENT_HANDLER)) {
			contentHandlers.add(CMOF_2_4_1_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(CMOF_2_4_CONTENT_HANDLER)) {
			contentHandlers.add(CMOF_2_4_CONTENT_HANDLER);
		}

		if (!contentHandlers.contains(CMOF_2_0_CONTENT_HANDLER)) {
			contentHandlers.add(CMOF_2_0_CONTENT_HANDLER);
		}

		return contentHandlerRegistry;
	}

	/**
	 * Adds resource URI mappings required for working with UML models to the
	 * specified map. These include at least mappings for the UML2-provided
	 * model libraries, metamodels, and profiles.
	 * 
	 * @param uriMap
	 *            a URI map, perhaps local to a resource set or perhaps the
	 *            global URI map
	 * 
	 * @return the same {@code uriMap}
	 * 
	 * @since 5.0
	 */
	public static Map<URI, URI> initURIConverterURIMap(Map<URI, URI> uriMap) {
		URI umlURI = getBaseUMLURI();
		mapURIs(uriMap, "platform:/plugin/org.eclipse.uml2.uml/model/", //$NON-NLS-1$
			umlURI.appendSegment("model"), "org.eclipse.uml2.uml"); //$NON-NLS-1$ //$NON-NLS-2$

		URI umlResourcesURI = getBaseUMLResourcesURI();
		mapURIs(uriMap, UMLResource.METAMODELS_PATHMAP,
			umlResourcesURI.appendSegment("metamodels"), //$NON-NLS-1$
			ResourcesPlugin.PLUGIN_ID);
		mapURIs(uriMap, UMLResource.PROFILES_PATHMAP,
			umlResourcesURI.appendSegment("profiles"), //$NON-NLS-1$
			ResourcesPlugin.PLUGIN_ID);
		mapURIs(uriMap, UMLResource.LIBRARIES_PATHMAP,
			umlResourcesURI.appendSegment("libraries"), //$NON-NLS-1$
			ResourcesPlugin.PLUGIN_ID);

		return uriMap;
	}

	/**
	 * Adds profile namespace URI mappings required for working with UML models
	 * to the specified map. These include at least mappings for the
	 * UML2-provided profiles.
	 * 
	 * @param ePackageNsURIToProfileLocationMap
	 *            a profile location map, perhaps local to a resource set or
	 *            perhaps the global location map
	 * 
	 * @return the same {@code ePackageNsURIToProfileLocationMap}
	 * 
	 * @since 5.0
	 */
	public static Map<String, URI> initEPackageNsURIToProfileLocationMap(
			Map<String, URI> ePackageNsURIToProfileLocationMap) {
		ePackageNsURIToProfileLocationMap.put(StandardPackage.eNS_URI,
			URI.createURI("pathmap://UML_PROFILES/Standard.profile.uml#_0")); //$NON-NLS-1$

		ePackageNsURIToProfileLocationMap.put(UMLResource.ECORE_PROFILE_NS_URI,
			URI.createURI("pathmap://UML_PROFILES/Ecore.profile.uml#_0")); //$NON-NLS-1$

		ePackageNsURIToProfileLocationMap.put(UMLResource.UML2_PROFILE_NS_URI,
			URI.createURI("pathmap://UML_PROFILES/UML2.profile.uml#_0")); //$NON-NLS-1$

		return ePackageNsURIToProfileLocationMap;
	}

	private static URI getBaseUMLURI() {
		URL resultURL = UMLUtil.class.getClassLoader()
			.getResource(String.format("model/%s", "UML.ecore")); //$NON-NLS-1$ //$NON-NLS-2$

		URI result;

		if (resultURL != null) {
			// remove the /model/UML.ecore segments of the resource
			// we found
			result = URI.createURI(resultURL.toExternalForm(), true)
				.trimSegments(2);
		} else {
			// probably, we're not running with JARs, so assume the source
			// project folder layout
			resultURL = UMLUtil.class.getResource("UMLUtil.class"); //$NON-NLS-1$

			String baseURL = resultURL.toExternalForm();

			int index = baseURL.lastIndexOf("/bin/"); //$NON-NLS-1$

			if (index != -1) {
				baseURL = baseURL.substring(0, index);
			}

			result = URI.createURI(baseURL, true);
		}

		return result;
	}

	private static URI getBaseUMLResourcesURI() {
		URI umlMetamodel = URI.createURI(UMLResource.UML_METAMODEL_URI);
		URL resultURL = UMLResourcesUtil.class.getClassLoader().getResource(
			String.format("metamodels/%s", umlMetamodel.lastSegment())); //$NON-NLS-1$

		URI result;

		if (resultURL != null) {
			// remove the /metamodel/UML.metamodel.uml segments of the resource
			// we found
			result = URI.createURI(resultURL.toExternalForm(), true)
				.trimSegments(2);
		} else {
			// probably, we're not running with JARs, so assume the source
			// project folder layout
			resultURL = UMLResourcesUtil.class
				.getResource("UMLResourcesUtil.class"); //$NON-NLS-1$

			String baseURL = resultURL.toExternalForm();

			int index = baseURL.lastIndexOf("/bin/"); //$NON-NLS-1$

			if (index != -1) {
				baseURL = baseURL.substring(0, index);
			}

			result = URI.createURI(baseURL, true);
		}

		return result;
	}

	private static void mapURIs(Map<URI, URI> uriMap, String uri, URI location,
			String pluginID) {

		URI prefix = URI.createURI(uri);

		// ensure trailing separator (make it a "URI prefix")
		if (!prefix.hasTrailingPathSeparator()) {
			prefix = prefix.appendSegment(""); //$NON-NLS-1$
		}

		// same with the location
		if (!location.hasTrailingPathSeparator()) {
			location = location.appendSegment(""); //$NON-NLS-1$
		}

		uriMap.put(prefix, location);

		// and platform URIs, too
		String folder = location.segment(location.segmentCount() - 2);
		String platformURI = String.format("%s/%s/", //$NON-NLS-1$
			pluginID, folder);
		uriMap.put(URI.createPlatformPluginURI(platformURI, true), location);
		uriMap.put(URI.createPlatformResourceURI(platformURI, true), location);
	}
}
