/*******************************************************************************
 * Copyright (c) 2005 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
 *******************************************************************************/
/*
 *  $$RCSfile: WorkbenchResourceHelperBase.java,v $$
 *  $$Revision: 1.2 $$  $$Date: 2005/02/15 23:04:14 $$ 
 */
package org.eclipse.jem.util.emf.workbench;

import java.util.*;

import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.jem.internal.util.emf.workbench.EMFWorkbenchContextFactory;
import org.eclipse.jem.internal.util.emf.workbench.WorkspaceResourceHandler;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;


/**
 * Workbench resource helper
 * 
 * @since 1.0.0
 */
public class WorkbenchResourceHelperBase {

	/**
	 * Everything is static, don't know why there is an instance here.
	 */
	public static final WorkbenchResourceHelperBase INSTANCE = new WorkbenchResourceHelperBase();

	protected static WorkspaceResourceHandler workspaceURILoader = new WorkspaceResourceHandler();

	protected static void resolveContainedProxies(EObject refObject) {
		List contained = refObject.eContents();
		EObject mofObject;
		for (int i = 0; i < contained.size(); i++) {
			mofObject = (EObject) contained.get(i);
			resolveProxies(mofObject);
		}
	}

	protected static void resolveNonContainedProxies(EObject refObject) {
		List references = refObject.eClass().getEAllReferences();
		EReference reference;
		for (int i = 0; i < references.size(); i++) {
			reference = (EReference) references.get(i);
			if (!reference.isContainment()) {
				if (reference.isMany()) {
					List value = (List) refObject.eGet(reference);
					for (int j = 0; j < value.size(); j++)
						value.get(j);
				} else {
					refObject.eGet(reference);
				}
			}
		}
	}

	/**
	 * Force all of the proxies with <code>resource</code> to be resolved.
	 * 
	 * @param resource
	 * 
	 * @since 1.0.0
	 */
	public static void resolveProxies(Resource resource) {
		if (resource != null) {
			List topLevels = resource.getContents();
			EObject mofObject;
			for (int i = 0; i < topLevels.size(); i++) {
				mofObject = (EObject) topLevels.get(i);
				resolveProxies(mofObject);
			}
		}
	}

	/**
	 * Return a List of proxies that are contained by the <code>resource</code>.
	 * 
	 * @param resource
	 * @return list of proxies.
	 * 
	 * @since 1.0.0
	 */
	public static List gatherProxies(Resource resource) {
		if (resource == null)
			return Collections.EMPTY_LIST;
		List list = new ArrayList();
		List topLevels = resource.getContents();
		int size = topLevels.size();
		EObject mofObject;
		for (int i = 0; i < size; i++) {
			mofObject = (EObject) topLevels.get(i);
			gatherProxies((InternalEObject) mofObject, list);
		}
		return list;
	}

	protected static void gatherProxies(InternalEObject refObject, List proxies) {
		if (refObject == null)
			return;
		List contains = refObject.eClass().getEAllContainments();
		if (contains != null) {
			int size = contains.size();
			EStructuralFeature sf = null;
			for (int i = 0; i < size; i++) {
				sf = (EStructuralFeature) contains.get(i);
				gatherProxies(refObject, sf, proxies);
			}
		}
	}

	protected static void gatherProxies(InternalEObject refObject, EStructuralFeature sf, List proxies) {
		Object value = null;
		InternalEObject proxy = null;
		if (sf.isMany() || refObject.eIsSet(sf)) {
			value = refObject.eGet(sf, false);
			if (value != null) {
				if (sf.isMany()) {
					Iterator j = ((InternalEList) value).basicIterator();
					while (j.hasNext()) {
						proxy = (InternalEObject) j.next();
						if (proxy.eIsProxy())
							proxies.add(proxy);
					}
				} else if (((InternalEObject) value).eIsProxy())
					proxies.add(value);
			}
		}
	}

	protected static void resolveProxies(EObject refObject) {
		if (refObject != null) {
			resolveNonContainedProxies(refObject);
			resolveContainedProxies(refObject);
		}
	}

	/**
	 * Return an existing context base on <code>aProject</code>.
	 * 
	 * @param aProject
	 * @return the context base for the project or <code>null</code> if none.
	 * 
	 * @since 1.0.0
	 */
	public static EMFWorkbenchContextBase getEMFContext(IProject aProject) {
		return EMFWorkbenchContextFactory.INSTANCE.getEMFContext(aProject);
	}

	/**
	 * Create a resource from the URI. The URI must contain the project name, either as the first segment, or if in platform resource url protocol.
	 * {@link #getResourceSet(URI)}
	 * 
	 * @param uri
	 * @return a new resource for the uri or <code>null</code> if not a project uri
	 * 
	 * @since 1.0.0
	 */
	public static Resource createResource(URI uri) {
		ResourceSet set = getResourceSet(uri);
		if (set != null)
			return set.createResource(uri);
		return null;
	}

	/**
	 * Check for a cached Resource for the given URI, if none is found, create a new Resource for with the URI against the proper ResourceSet.
	 * 
	 * @param uri
	 * @return resource or <code>null</code> if not a project uri.
	 * 
	 * @since 1.0.0
	 */
	public static Resource getExistingOrCreateResource(URI uri) {
		return getExistingOrCreateResource(uri, getResourceSet(uri));
	}

	/**
	 * Check for a cached Resource for the given URI, if none is found, create a new Resource for with the URI against the given ResourceSet.
	 * 
	 * @param uri
	 * @param set
	 * @return resource or <code>null</code> if set was <code>null</code>.
	 * 
	 * @since 1.0.0
	 */
	public static Resource getExistingOrCreateResource(URI uri, ResourceSet set) {
		Resource res = null;
		if (set != null) {
			res = set.getResource(uri, false);
			if (res == null)
				res = set.createResource(uri);
		}
		return res;
	}

	/**
	 * Return a new or existing context base on <code>aProject</code>. Allow the <code>contributor</code> to contribute to the new or existing
	 * nature prior to returning.
	 * 
	 * @param aProject
	 * @param contributor
	 * @return the context base for the project.
	 * 
	 * @since 1.0.0
	 */
	public static EMFWorkbenchContextBase createEMFContext(IProject aProject, IEMFContextContributor contributor) {
		return EMFWorkbenchContextFactory.INSTANCE.createEMFContext(aProject, contributor);
	}

	/**
	 * Does the passed URI have the form platform:/resource/... ?
	 * 
	 * @param uri
	 * @return <code>true</code> if it is a platform resource protocol.
	 * 
	 * @since 1.0.0
	 */
	public static boolean isPlatformResourceURI(URI uri) {
		return JEMUtilPlugin.PLATFORM_PROTOCOL.equals(uri.scheme()) && JEMUtilPlugin.PLATFORM_RESOURCE.equals(uri.segment(0));
	}

	/**
	 * This api may be used to cache a Resource if it has a URI that is Workspace relative. Return true if it is cached.
	 * 
	 * @param aResource
	 * @return <code>true</code> if it was successful to cache.
	 * 
	 * @since 1.0.0
	 */
	public static boolean cacheResource(Resource aResource) {
		if (aResource != null) {
			ResourceSet set = getResourceSet(aResource.getURI());
			if (set != null)
				return set.getResources().add(aResource);
		}
		return false;
	}

	/**
	 * This api is used if you create a new MOF resource and you want to add it to the correct ResourceSet. In order to do that, we need the IProject
	 * that you want aResource to be cached within as well as the IPath which is the full path of the location of the new Resource.
	 * 
	 * @param aProject
	 * @param aResource
	 * @param fullPath
	 * @return <code>true</code> if resource was cached.
	 * 
	 * @since 1.0.0
	 */
	public static boolean cacheResource(IProject aProject, Resource aResource, IPath fullPath) {
		if (aProject == null || aResource == null || !aProject.isAccessible())
			return false;
		ResourceSet set = getResourceSet(aProject);
		if (set != null) {
			URI converted = set.getURIConverter().normalize(aResource.getURI());
			if (converted != aResource.getURI())
				aResource.setURI(converted);
			return set.getResources().add(aResource);
		}
		return false;
	}

	/**
	 * Get the path of the project resource relative to the workspace or relative to the list of containers in this project.
	 * 
	 * @param aResource
	 * @return path
	 * 
	 * @since 1.0.0
	 */
	public static String getActualProjectRelativeURI(IResource aResource) {
		if (aResource == null || !aResource.isAccessible())
			return null;
		IProject project = aResource.getProject();
		IPath path = getPathInProject(project, aResource.getFullPath());
		return path.makeRelative().toString();
	}

	/**
	 * Return an IPath that can be used to load a Resource using the <code>fullPath</code>. This will be a project relative path.
	 * 
	 * @param project
	 * @param fullPath
	 * @return path
	 * 
	 * @since 1.0.0
	 */
	public static IPath getPathInProject(IProject project, IPath fullPath) {
		List containers = getProjectURIConverterContainers(project);
		if (!containers.isEmpty())
			return getPathFromContainers(containers, fullPath);
		return fullPath;
	}

	protected static List getProjectURIConverterContainers(IProject project) {
		EMFWorkbenchContextBase nature = createEMFContext(project, null);
		if (nature != null) {
			WorkbenchURIConverter conv = (WorkbenchURIConverter) nature.getResourceSet().getURIConverter();
			if (conv != null)
				return conv.getInputContainers();
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * If this path is contained within one of the listed containers, then return the path relative to the container.
	 * 
	 * @param containers
	 * @param fullPath
	 * @return path relative to a container, or unchanged path if not in a container.
	 * 
	 * @since 1.0.0
	 */
	public static IPath getPathFromContainers(List containers, IPath fullPath) {
		IContainer container = null;
		IPath result;
		int size = containers.size();
		int matching = -1;
		IPath containerPath;
		for (int i = 0; i < size; i++) {
			container = (IContainer) containers.get(i);
			containerPath = container.getFullPath();
			matching = fullPath.matchingFirstSegments(containerPath);
			if (matching > 0 && matching == containerPath.segmentCount()) {
				result = fullPath.removeFirstSegments(matching);
				result = result.makeRelative();
				return result;
			}
		}
		return fullPath;
	}

	/**
	 * Return true if the <code>uri</code> has its container segments visible from the input containers for the <code>project</code>.
	 * 
	 * @param project
	 * @param uri
	 * @return <code>true</code> if the uri is visible from the input containers.
	 * 
	 * @since 1.0.0
	 */
	public static boolean hasContainerStructure(IProject project, URI uri) {
		if (project != null && uri != null) {
			IPath path = new Path(uri.toString());
			List containers = getProjectURIConverterContainers(project);
			int segmentCount = path.segmentCount();
			IPath containerPath = segmentCount > 1 ? path.removeLastSegments(1) : null;
			IContainer container = null;
			for (int i = 0; i < containers.size(); i++) {
				container = (IContainer) containers.get(i);
				if (!container.isAccessible())
					continue;
				if (segmentCount == 1) {
					if (container == project)
						return true;
				} else if (containerPath != null) {
					IFolder folder = container.getFolder(containerPath);
					if (folder != null && folder.isAccessible())
						return true;
				}
			}
		}
		return false;
	}

	/**
	 * Get the resource for the uri.
	 * 
	 * @param uri
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static Resource getResource(URI uri) {
		return workspaceURILoader.getResource(null, uri);
	}

	/**
	 * Return the Resource for the passed IFile without forcing a load.
	 * 
	 * @param aFile
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static Resource getResource(IFile aFile) {
		return getResource(aFile, false);
	}

	/**
	 * Return the Resource for the passed IFile, forcing a load if <code>loadOnDemand</code> says so.
	 * 
	 * @param aFile
	 * @param loadOnDemand
	 *            <code>true</code> will force a load of resource if not loaded.
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static Resource getResource(IFile aFile, boolean loadOnDemand) {
		if (aFile != null)
			return getResource(URI.createPlatformResourceURI(aFile.getFullPath().toString()), loadOnDemand);
		return null;
	}

	/**
	 * Return the Resource for the passed IFile without a load if not loaded.
	 * 
	 * @param aFile
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static Resource load(IFile aFile) {
		return getResource(aFile, true);
	}

	/**
	 * This method will direct the getResource(URI, boolean) call to the correct ProjectResourceSet based on the project name in the URI.
	 * 
	 * @param uri
	 *            This must be an absolute URI of the form platform:/resource/...
	 * @param loadOnDemand
	 *            <code>true</code> will force the resource to be loaded if not already loaded.
	 * @return Resource
	 */
	public static Resource getResource(URI uri, boolean loadOnDemand) {
		ResourceSet set = getResourceSet(uri);
		if (set != null)
			return set.getResource(uri, loadOnDemand);
		return null;
	}

	/**
	 * Return a ResourceSet for the passed URI. The URI should be in the format platform:/resource/{project name}/... or {project name}/... for this
	 * api to work.
	 * 
	 * @param uri
	 * @return the resource set or <code>null</code> if not of correct form or project doesn't have a resource set.
	 * 
	 * @since 1.0.0
	 */
	public static ResourceSet getResourceSet(URI uri) {
		String projectName = null;
		if (isPlatformResourceURI(uri))
			projectName = uri.segment(1);
		else {
			projectName = new org.eclipse.core.runtime.Path(uri.path()).segment(0);
		} //assume project name is first in the URI
		IProject project = getWorkspace().getRoot().getProject(projectName);
		if (project != null && project.isAccessible())
			return getResourceSet(project);
		return null;
	}

	/**
	 * Return the ResourceSet for the passed IProject.
	 * 
	 * @param project
	 * @return resource set
	 */
	public static ResourceSet getResourceSet(IProject project) {
		EMFWorkbenchContextBase nat = createEMFContext(project, null);
		if (nat != null)
			return nat.getResourceSet();
		return null;
	}

	/**
	 * Get the workspace. (just use {@link ResourcesPlugin#getWorkspace()}).
	 * 
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	/**
	 * Get the project associated with the resource set.
	 * 
	 * @param set
	 * @return project or <code>null</code> if resource set not associated with a project.
	 * 
	 * @since 1.0.0
	 */
	public static IProject getProject(ResourceSet set) {
		if (set != null) {
			if (set instanceof ProjectResourceSet) {
				ProjectResourceSet pset = (ProjectResourceSet) set;
				return pset.getProject();
			}
		}
		return null;
	}

	protected static boolean isRegisteredURIMapping(String href) {
		if (href != null) {
			String file = href;
			int index = href.indexOf('#');
			if (index > -1)
				file = href.substring(0, index);
			return URIConverter.URI_MAP.get(file) != null;
		}
		return false;
	}

	/**
	 * Remove all of the resources from the resource set and then unload them. Unload forces all of the objects to become proxies so next resolve will
	 * reload the resource.
	 * 
	 * @param resources
	 * @param aSet
	 * 
	 * @since 1.0.0
	 */
	public static void removeAndUnloadAll(List resources, ResourceSet aSet) {
		if (aSet == null || resources == null || resources.isEmpty())
			return;
		aSet.getResources().removeAll(resources);
		Resource res;
		for (int i = 0; i < resources.size(); i++) {
			res = (Resource) resources.get(i);
			res.unload();
		}
	}

	/**
	 * Turn object into a proxy.
	 * 
	 * @param anObject
	 * @return <code>true</code> if object was able to become a proxy.
	 * 
	 * @since 1.0.0
	 */
	public static boolean becomeProxy(EObject anObject) {
		if (anObject != null) {
			Resource res = anObject.eResource();
			if (res != null) {
				URI uri = res.getURI();
				((InternalEObject) anObject).eSetProxyURI(uri.appendFragment(res.getURIFragment(anObject)));
				//anObject.eAdapters().clear();
				return true;
			}
		}
		return false;
	}

	/**
	 * Return true if the WrappedException is actually a Resource Not Found.
	 * 
	 * @param wrappedEx
	 * @return <code>true</code> is exception wrappers a resource not found.
	 * @since 1.0.0
	 */
	public static boolean isResourceNotFound(WrappedException wrappedEx) {
		Exception excep = wrappedEx.exception();
		while (excep instanceof WrappedException) {
			excep = ((WrappedException) excep).exception();
		}
		return primIsResourceNotFound(excep);
	}

	private static boolean primIsResourceNotFound(Exception excep) {
		if (excep instanceof ResourceException) {
			IStatus status = ((ResourceException) excep).getStatus();
			return status.getCode() == IResourceStatus.RESOURCE_NOT_FOUND;
		}
		return false;
	}

	/**
	 * Return true if the WrappedException is actually a Resource Not Found.
	 * 
	 * @param wrappedEx
	 * @return <code>true</code> is exception wrappers a resource not found.
	 * @since 1.0.0
	 */
	public static boolean isResourceNotFound(Resource.IOWrappedException wrappedEx) {
		return primIsResourceNotFound(wrappedEx.getWrappedException());
	}

	/**
	 * Return a URI represenation of the platformURI without the leading "platform:/resource/" if present.
	 * 
	 * @param platformURI
	 * @return uri
	 * @since 1.0.0
	 */
	public static URI getNonPlatformURI(URI platformURI) {
		if (isPlatformResourceURI(platformURI)) {
			String uriString = primGetNonPlatformURIString(platformURI);
			return URI.createURI(uriString);
		}
		return platformURI;
	}

	/**
	 * Return a String represenation of the platformURI without the leading "platform:/resource/" if present.
	 * 
	 * @param platformURI
	 * @return
	 * @since 1.0.0
	 */
	public static String getNonPlatformURIString(URI platformURI) {
		if (isPlatformResourceURI(platformURI)) { return primGetNonPlatformURIString(platformURI); }
		return platformURI.toString();
	}

	/*
	 * Remove "platform:/resource/" from the front of the platformURI and return the remaining String.
	 */
	private static String primGetNonPlatformURIString(URI platformURI) {
		String uriString = platformURI.toString();
		//"platform:/resource/" is 19 characters.
		return uriString.substring(19, uriString.length());
	}

	/**
	 * Does the passed URI have the form platform:/plugin/... ?
	 * 
	 * @param uri
	 * @return <code>true</code> if uri is platform plugin protocol.
	 * 
	 * @since 1.0.0
	 */
	public static boolean isPlatformPluginResourceURI(URI uri) {
		return JEMUtilPlugin.PLATFORM_PROTOCOL.equals(uri.scheme()) && JEMUtilPlugin.PLATFORM_PLUGIN.equals(uri.segment(0));
	}

}