/*******************************************************************************
 * Copyright (c) 2007, 2018 Borland Software Corporation 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:
 *     Borland Software Corporation - initial API and implementation
 *     Christopher Gerking - bugs 428620, 537041
 *     Ed Willink - bug 533564
 *******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.emf.util;

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

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
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.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.osgi.util.NLS;

/**
 * @author pkobiakov
 */
public class EmfUtil {
	private EmfUtil() {}

	public static final String PATH_SEPARATOR = "::"; //$NON-NLS-1$

	public static ModelContent loadModel(URI uri) {
		return loadModel(uri, getDefaultLoadOptions(), null);
	}

	public static ModelContent loadModel(URI uri, ResourceSet rs) {
		return loadModel(uri, getDefaultLoadOptions(), rs);
	}

	private static ModelContent loadModel(URI uri, Map<Object, Object> options, ResourceSet rs) {
		if(uri == null) {
			return null;
		}
		ResourceSet resourceSet = (rs != null) ? rs : createResourceSet(options);
		Map<URI, URI> uriMap = resourceSet.getURIConverter().getURIMap();
		Map<URI, URI> platformURIMap = EcorePlugin.computePlatformURIMap(true);
		uriMap.putAll(platformURIMap);
		String fragment = uri.fragment();
		if (fragment != null && fragment.length() > 0) {
			EObject eObject = resourceSet.getEObject(uri, true);
			if (eObject == null) {
				return null;
			}
			return new ModelContent(Collections.singletonList(eObject));
		}
		Resource resource = resourceSet.getResource(uri.trimFragment(), true);
		if (resource == null) {
			return null;
		}
		return new ModelContent(resource.getContents());
	}

	public static ModelContent safeLoadModel(URI uri, ResourceSet rs) {
		return safeLoadModel(uri, getDefaultLoadOptions(), rs);
	}

	private static ModelContent safeLoadModel(URI uri, Map<Object, Object> options, ResourceSet rs) {
		try {
			return loadModel(uri, options, rs);
		}
		catch(Exception e){
			return null;
		}
	}

	public static Resource loadResource(URI uri) {
		return createResourceSet(getDefaultLoadOptions()).getResource(uri, true);
	}

	private static ResourceSet createResourceSet(Map<Object, Object> options) {
		ResourceSet resourceSet = new ResourceSetImpl();
		resourceSet.getLoadOptions().putAll(options);
		
		return resourceSet;
	}

	public static EObject resolveSource(EObject in, EObject inputType) {
		if (inputType == null || inputType.eResource() == null) {
			return in;
		}
		return resolveSource(in, inputType.eResource().getResourceSet());
	}

	public static EObject resolveSource(EObject in, ResourceSet rs) {
		if (rs != null && EmfUtil.isDynamic(in)) {
			ResourceSet inRS = in.eResource() != null ? in.eResource().getResourceSet() : null;
			if (rs != inRS) {
				URI uri = EcoreUtil.getURI(in);
				if (uri != null && !"#//".equals(uri.toString())) { //$NON-NLS-1$
					return rs.getEObject(uri, true);
				}
			}
		}
		return in;
	}

	public static Set<EObject> getResolvedContent(Collection<EObject> content, EObject metamodel) {
		ResourceSet rs = (metamodel != null && metamodel.eResource() != null ? metamodel.eResource().getResourceSet() : null);
		return getResolvedContent(content, rs);
	}

	public static Set<EObject> getResolvedContent(Collection<EObject> content, ResourceSet rs) {
		Set<EObject> resolvedObjs = new LinkedHashSet<EObject>(content.size());
		for (EObject obj : content) {
			EObject resolved = null;
			try {
				resolved = resolveSource(obj, rs);
			}
			catch (Exception ex) {
			}
			resolvedObjs.add(resolved != null ? resolved : obj);
		}
		return resolvedObjs;
	}

	public static boolean isUriExistsAsEObject(URI uri, ResourceSet rs, boolean validateNonEmpty) {
		ModelContent loadModel = null;
		try {
			loadModel = loadModel(uri, rs);
		}
		catch (Exception e) {
		}
		if (loadModel == null) {
			return false;
		}
		return validateNonEmpty ? !loadModel.getContent().isEmpty() : true;
	}

	public static boolean isDynamic(EObject eObject) {
		return eObject instanceof EStructuralFeature.Internal.DynamicValueHolder;
	}


	public static void saveModel(EObject eObject, URI uri, Map<Object, Object> opts) throws EmfException {
		ResourceSet resourceSet = getOutputResourceSet();

		Resource resource = resourceSet.createResource(uri);
		resource.getContents().add(eObject);

		Map<Object, Object> options = new HashMap<Object, Object>(opts);
		options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$

		if(isDynamic(eObject)) {
			options.put("SCHEMA_LOCATION", Boolean.TRUE); //$NON-NLS-1$
		}

		try {
			resource.save(options);
		} catch (Exception e) {
			throw new EmfException(NLS.bind(Messages.EmfUtil_1, uri), e);
		}
	}

	public static void saveModel(Resource modelExtent, Map<Object, Object> opts) throws EmfException {
		Map<Object, Object> options = new HashMap<Object, Object>(opts);
		options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		options.put(XMIResource.OPTION_PROCESS_DANGLING_HREF, XMIResource.OPTION_PROCESS_DANGLING_HREF_DISCARD);
		for (EObject eObject : modelExtent.getContents()) {
			if(isDynamic(eObject)) {
				options.put("SCHEMA_LOCATION", Boolean.TRUE); //$NON-NLS-1$
				break;
			}
		}

		try {
			modelExtent.save(options);
		} catch (Exception e) {
			throw new EmfException(NLS.bind(Messages.EmfUtil_1, modelExtent.getURI()), e);
		}
	}

	public static ResourceSet getOutputResourceSet() {
		return new ResourceSetImpl();
	}

	public static EPackage getRootPackage(EPackage pack) {
		EPackage parent = pack.getESuperPackage();
		if(parent == null) {
			return pack;
		}
		else {
			return getRootPackage(parent);
		}
	}

	public static String getFullName(EClassifier cls) {
		return getFullName(cls, PATH_SEPARATOR);
	}

	private static String getFullName(EClassifier cls, String delim) {
		if(cls.getEPackage() == null) {
			return cls.getName();
		}
		return getFullName(cls.getEPackage(), delim) + delim + cls.getName();
	}

	public static String getFullName(EPackage pack) {
		return getFullName(pack, PATH_SEPARATOR);
	}

	private static String getFullName(EPackage pack, String delim) {
		if(pack.getESuperPackage() != null) {
			return getFullName(pack.getESuperPackage(), delim) + delim + pack.getName();
		} else {
			return pack.getName();
		}
	}

	/**
	 * Get the given package full name relative to the specified owning package
	 *
	 * @param ePackage
	 *            the package of which to retrieve the full name
	 * @param baseOwningPackage
	 *            the package representing the root context for relative name
	 *            resolution.
	 *            <p>
	 *            This package and its possible super-packages will be excluded
	 *            from the full-name. If it is the immediate owning package of
	 *            the <code>ePackage</code>, the local name of <code>ePackage</code> is
	 *            returned.
	 */
	public static String getFullNameRelativeToPackage(EPackage ePackage, EPackage baseQwningPackage) {
		if(ePackage.getESuperPackage() != null && ePackage.getESuperPackage() != baseQwningPackage) {
			StringBuilder buf = new StringBuilder();

			EPackage nextPackage = ePackage;
			for(int i = 0; nextPackage != null && nextPackage != baseQwningPackage ; i++) {
				if(i > 0) {
					buf.insert(0, PATH_SEPARATOR);
				}
				buf.insert(0, nextPackage.getName());

				nextPackage = nextPackage.getESuperPackage();
			}

			return getFullNameRelativeToPackage(ePackage.getESuperPackage(), baseQwningPackage) + PATH_SEPARATOR + ePackage.getName();
		} else {
			return ePackage.getName();
		}
	}

	/**
	 * Get the given classifier's full name relative to the specified owning package
	 *
	 * @param eClassifier
	 *            the classifier of which to retrieve name
	 * @param baseOwningPackage
	 *            the package representing the root context for relative name
	 *            resolution.
	 *            <p>
	 *            This package and its possible super-packages will be excluded
	 *            from the full-name. If it is the immediate owning package of
	 *            the given classifier, the local name of the classifier is
	 *            returned.
	 */
	public static String getFullNameRelativeToPackage(EClassifier eClassifier, EPackage baseOwningPackage) {
		EPackage immediateOwner = eClassifier.getEPackage();
		if(baseOwningPackage != null && immediateOwner != null && baseOwningPackage != immediateOwner) {
			String parentName = EmfUtil.getFullNameRelativeToPackage(immediateOwner, baseOwningPackage);
			return parentName + PATH_SEPARATOR + eClassifier.getName();
		}
		return eClassifier.getName();
	}

	public static EClass getEClass(EPackage root, String[] fullName) throws EmfException {
		EClassifier classifier = getEClassifier(root, fullName);
		if(classifier instanceof EClass == false) {
			throw new EmfException(NLS.bind(Messages.EmfUtil_6, fullName[fullName.length-1]));
		}

		return (EClass)classifier;
	}

	private static EClassifier getEClassifier(EPackage root, String[] fullName) throws EmfException {
		if(fullName.length < 2) {
			throw new EmfException(NLS.bind(Messages.EmfUtil_2, Arrays.asList(fullName)));
		}

		String rootPackName = fullName[0];
		if(!rootPackName.equals(root.getName())) {
			throw new EmfException(NLS.bind(Messages.EmfUtil_3, rootPackName, root.getName()));
		}

		MAIN:
			for(int i = 1; i < fullName.length-1; i++) {
				for (EPackage pack : root.getESubpackages()) {
					if(fullName[i].equals(pack.getName())) {
						root = pack;
						continue MAIN;
					}
				}

				throw new EmfException(NLS.bind(Messages.EmfUtil_5, fullName[i]));
			}

		EClassifier classifier = root.getEClassifier(fullName[fullName.length-1]);
		return classifier;
	}

	public static URI makeUri(String uriString) {
		if(uriString == null || uriString.length() == 0) {
			return null;
		}

		URI uri = null;
		try {
			uri = URI.createURI(uriString);
		}
		catch (Exception e) {
			return null;
		}

		return uri;
	}

	public static String getRootPackageUri(EClassifier cls) {
		String uri = cls == null ? null : getRootPackage(cls.getEPackage()).getNsURI();
		return uri;
	}

	public static boolean isAssignableFrom(EClassifier type, EClassifier from) {
		if (type == from) {
			return true;
		}
		if (false == from instanceof EClass) {
			return false;
		}
		return ((EClass) from).getEAllSuperTypes().contains(type);
	}

	public static Map<Object, Object> getDefaultLoadOptions() {
		Map<Object, Object> options = new HashMap<Object, Object>();
		// create new session to avoid problems with parallel filling of containments lists (#31662, etc.)
		return options;
	}

	public static Resource createResource(URI uri, ResourceSet outResourceSet) {
		Resource resource = outResourceSet.createResource(uri);
		if(resource != null) {
			return resource;
		}

		Object possibleFactory = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().get(uri.fileExtension());
		Resource.Factory factory = null;
		if (possibleFactory instanceof Resource.Factory) {
			factory = (Resource.Factory) possibleFactory;
		}
		if (possibleFactory instanceof Resource.Factory.Descriptor) {
			factory = ((Resource.Factory.Descriptor) possibleFactory).createFactory();
		}

		if(factory == null) {
			factory = new XMIResourceFactoryImpl();
		}

		return factory.createResource(uri);
	}

	public static boolean isUriMapped(ResourceSet resourceSet, URI uri) {
		if (uri != null) {
			URIConverter converter = resourceSet.getURIConverter();
			if (converter != null) {
				Map<URI, URI> uriMap = converter.getURIMap();
				if (uriMap != null) {
					return uriMap.containsKey(uri);
				}
			}
		}
		return false;
	}

	public static void cleanupResourceSet(ResourceSet rs) {
		URI uri = URI.createURI(""); //$NON-NLS-1$

		List<Resource> resCopy = new ArrayList<Resource>(rs.getResources());
		for (Resource res : resCopy) {
			if (res.eAdapters().contains(RESOURCE_PERSISTED_ADAPTER)) {
				continue;
			}

			//			for (TreeIterator<EObject> it = res.getAllContents(); it.hasNext();) {
			//				EObject eObject = it.next();
			//				eObject.eAdapters().clear();
			//			}
			//			res.getContents().clear();
			//			res.eAdapters().clear();

			if (res.isLoaded()) {
				for (TreeIterator<EObject> it = res.getAllContents(); it.hasNext();) {
					EObject eObject = it.next();
					((InternalEObject) eObject).eSetProxyURI(uri);
				}
				res.unload();
			}
		}
		rs.getResources().clear();
		rs.eAdapters().clear();
	}

	public static boolean isUriExists(URI uri, ResourceSet rs, boolean validateNonEmpty) {
		URIConverter uriConverter = (rs != null ? rs.getURIConverter() : URIConverter.INSTANCE);
		if (uriConverter.exists(uri, Collections.emptyMap())) {
			return true;
		}
		return isUriExistsAsEObject(uri, rs, validateNonEmpty);
	}
	
	public static EPackage getFirstEPackageContent(Resource resource) {
		for (EObject content : resource.getContents()) {
			if (content instanceof EPackage) {
				return (EPackage) content;
			}
		}
		return null;
	}
	
	
	public static final Adapter RESOURCE_PERSISTED_ADAPTER = new AdapterImpl();

	public static final Map<Object, Object> DEFAULT_SAVE_OPTIONS = new HashMap<Object, Object>();
	static {
		DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
	}
	
}
