/*******************************************************************************
 * Copyright (c) 2003, 2007 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.wst.common.componentcore.internal.impl;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Factory;
import org.eclipse.jem.util.RegistryReader;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.ModulecorePlugin;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.internal.emf.resource.FileNameResourceFactoryRegistry;
import org.eclipse.wst.common.internal.emf.resource.ResourceFactoryDescriptor;
import org.eclipse.wst.common.internal.emf.utilities.DefaultOverridableResourceFactoryRegistry;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.edit.EMFWorkbenchEditContextFactory;

/**
 * <p>
 * The following class is experimental until fully documented.
 * </p>
 */
public class WTPResourceFactoryRegistry extends FileNameResourceFactoryRegistry {

	public static final WTPResourceFactoryRegistry INSTANCE = new WTPResourceFactoryRegistry();
	 
	private final static boolean LOG_WARNINGS = false;
	
	
	private WTPResourceFactoryRegistry() {
		new ResourceFactoryRegistryReader().readRegistry();
	}
	
	public Resource.Factory delegatedGetFactory(URI uri) {
		if (WTPResourceFactoryRegistry.INSTANCE == this)
			return super.delegatedGetFactory(uri);
		return WTPResourceFactoryRegistry.INSTANCE.getFactory(uri);	
	}   

	public Resource.Factory getFactory(URI uri, IContentDescription description) {
		IProject componentProject = null;
		try {
			componentProject = StructureEdit.getContainingProject(uri);
		} catch (UnresolveableURIException e) {
			// don't do anything
		}
		ILock lock = EMFWorkbenchEditContextFactory.getProjectLockObject(componentProject);
		try{
			if(null != lock){
				lock.acquire();
			}
			synchronized(this){
				Resource.Factory resourceFactory = null;
				if(uri != null && uri.lastSegment() != null) {
					ResourceFactoryDescriptor descriptor = null;
					if(null == description){
						descriptor = getDescriptor(uri);
					} else {
						descriptor = getDescriptor(uri, description);
					}
					
					if(descriptor != null) {
						resourceFactory = getFactory(descriptor);	
					}	
				}
				if(resourceFactory == null)
					resourceFactory = super.getFactory(uri);
				return resourceFactory;
			}
		} finally{
			if(null != lock){
				lock.release();
			}
		} 
	}
	
	public Resource.Factory getFactory(URI uri) {
		return getFactory(uri, (IContentDescription)null);
	}	


	/**
	 * Register a file name representing the last segment of a URI with the corresponding
	 * Resource.Factory.
	 */
	public synchronized void registerLastFileSegment(String aSimpleFileName, Resource.Factory aFactory) { 
		
		if(LOG_WARNINGS) {
			/* the third entry in the array is this stack frame, we walk back from there. */
			StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
			if(stackTrace.length > 4) {
				StringBuffer warningMessage = new StringBuffer("WTPResourceFactoryRegistry.registerLastFileSegment() was called explicitly from " + stackTrace[3]);
				warningMessage.append("\nThis happened around: \n");
				for (int i = 4; (i < stackTrace.length) && i < 8; i++) {
					warningMessage.append("\tnear ").append(stackTrace[i]).append('\n');
				}
				warningMessage.append(".\nClients should use the org.eclipse.wst.common.modulecore.resourceFactories extension point instead.");
				ModulecorePlugin.log(IStatus.INFO, 0, warningMessage.toString(), null);		
			}
		}
		
		super.registerLastFileSegment(aSimpleFileName, aFactory);
		
	}  
	private WTPResourceFactoryRegistryKey getKey(ResourceFactoryDescriptor descriptor) {
		WTPResourceFactoryRegistryKey key = new WTPResourceFactoryRegistryKey();
		key.shortName = descriptor.getShortSegment();
		key.type = descriptor.getContentType();
		key.isDefault = descriptor.isDefault();
		if(descriptor instanceof ConfigurationResourceFactoryDescriptor){
			ConfigurationResourceFactoryDescriptor configurationDescriptor = (ConfigurationResourceFactoryDescriptor)descriptor;
			key.factoryClassName = configurationDescriptor.getFactoryClassName();
			key.overridesFactoryClassName = configurationDescriptor.getOverridesFactoryClassName();
		}
		return key;
	}
	
	/**
	 * Declares a subclass to create Resource.Factory(ies) from an extension. 
	 */
	private class ConfigurationResourceFactoryDescriptor extends ResourceFactoryDescriptor  implements IResourceFactoryExtPtConstants {
		
		private String shortSegment;
		private IContentType contentType;
		private boolean isDefault = true;
		private String factoryClassName = null;
		private String overridesFactoryClassName = null;
		private final IConfigurationElement element; 
		
		public ConfigurationResourceFactoryDescriptor(IConfigurationElement ext) throws CoreException {
			Assert.isNotNull(ext);
			element = ext;
			init();
		} 
		
		public String getOverridesFactoryClassName() {
			return overridesFactoryClassName;
		}

		public String getFactoryClassName() {
			return factoryClassName;
		}

		private void init() throws CoreException {
			shortSegment = element.getAttribute(ATT_SHORT_SEGMENT);
			
			IConfigurationElement[] bindings = element.getChildren(TAG_CONTENTTYPE);
			if (bindings.length > 0) {
				String contentTypeId = null;
				contentTypeId = bindings[0].getAttribute(ATT_CONTENTTYPEID);			
				if (contentTypeId != null)
					contentType = Platform.getContentTypeManager().getContentType(contentTypeId);
			}
			
			if ((shortSegment == null || shortSegment.trim().length() == 0)
						&& contentType == null) {
				throw new CoreException(
							ModulecorePlugin.createErrorStatus(0, 
										"Either the shortSegment attribute or the contentType element of " //$NON-NLS-1$
										+ TAG_RESOURCE_FACTORY 
										+ " must be specified in " 
										+ element.getNamespaceIdentifier()
										+ ".  The shortSegment attribute is specified with a valid, non-null, " //$NON-NLS-1$
										+ "non-empty value, and the contentType element is specified with a " //$NON-NLS-1$
										+ "valid, non-null, non-empty contentTypeId." //$NON-NLS-1$
										, null));
			}
			
			if ("false".equals(element.getAttribute(ATT_ISDEFAULT)))
				isDefault = false;
				
            factoryClassName = element.getAttribute(ATT_CLASS);
			overridesFactoryClassName = element.getAttribute(ATT_OVERRIDES_FACTORY);				
		} 

		public boolean isEnabledFor(URI fileURI) {
			// Not sure where this is actually used, so not sure what the proper 
			// implementation should be, so simply checking the short segment for now
			if (fileURI != null && fileURI.lastSegment() != null && shortSegment != null) {
				return shortSegment.equals(fileURI.lastSegment());
			}
			return false;
		} 
		
		public Resource.Factory createFactory() {
			
			final Resource.Factory[] factory = new Resource.Factory[1];
			
			SafeRunner.run(new ISafeRunnable() {
				
				public void run() throws Exception {
					factory[0] = (Resource.Factory) element.createExecutableExtension(ATT_CLASS);					
				}
				
				public void handleException(Throwable exception) {
					ModulecorePlugin.log(ModulecorePlugin.createErrorStatus(0, exception.getMessage(), exception));					
				}
			});
			
			return factory[0] != null ? factory[0] : DefaultOverridableResourceFactoryRegistry.GLOBAL_FACTORY;
			
		}

		public String getShortSegment() {
			return shortSegment;
		}

		public IContentType getContentType() {
			return contentType;
		}

		public boolean isDefault() {
			return isDefault;
		}
		
		public int hashCode() {
			int hashCode = 0;
			if (getContentType() != null) {
				hashCode |= getContentType().hashCode();
			}
			if (getShortSegment() != null) {
				hashCode |= getShortSegment().hashCode();
			}
			return hashCode;
		}
		
		public boolean equals(Object o) {
			if (! (o instanceof ResourceFactoryDescriptor)) {
				return false;
			}
			ResourceFactoryDescriptor rfdo = (ResourceFactoryDescriptor) o;
			boolean equals = true;
			equals &= (getContentType() == null) ? rfdo.getContentType() == null :
				getContentType().equals(rfdo.getContentType());
			equals &= (getShortSegment() == null) ? rfdo.getShortSegment() == null :
				getShortSegment().equals(rfdo.getShortSegment());
			return equals;
		}
	}
	 
	
	private class ResourceFactoryRegistryReader extends RegistryReader implements IResourceFactoryExtPtConstants { 
 		
		public ResourceFactoryRegistryReader() {
			super(ModulecorePlugin.PLUGIN_ID, EXTPT_RESOURCE_FACTORIES);
		}

		public boolean readElement(final IConfigurationElement element) {
			
			if(element != null && TAG_RESOURCE_FACTORY.equals(element.getName())) {
				final boolean[] success = new boolean[] { true }; 
				SafeRunner.run(new ISafeRunnable() {
					
					public void run() throws Exception {
						addDescriptor(new ConfigurationResourceFactoryDescriptor(element));
					} 

					public void handleException(Throwable exception) {
						ModulecorePlugin.log(ModulecorePlugin.createErrorStatus(0, exception.getMessage(), exception));
						success[0] = false;
					}
				});				
				return success[0];
			} else {
				return false;
			}	
		}
	}
	private class WTPResourceFactoryRegistryKey { 
 		
		public String overridesFactoryClassName;
		public String factoryClassName;
		public String shortName;
		public IContentType type;
		public boolean isDefault = true;
		public WTPResourceFactoryRegistryKey() {
			super();
		}
		
		/**
		 * Sort in the following manner:
		 * First, sort by shortName, if shortName is null, then it comes last
		 * If shortNames are equal, then sort by isDefault
		 * If isDefault is also equal, then the one defining a factoryClassName wins
		 * If both have factoryClassNames, then check to see if one overrides the other via overridesFactoryClassName
		 * If neither override the other factory class, then sort by factoryClassname
		 * @param other
		 * @return
		 */
		public int compareTo(WTPResourceFactoryRegistryKey other){
			if(this == other){
				return 0;
			}
			if(shortName == null && other.shortName == null){
				return 0;
			} else if(shortName == null){
				return 1;
			} else if(other.shortName == null){
				return -1;
			}
			
			int shortNameCompare = this.shortName.compareTo(other.shortName);
			if(shortNameCompare != 0){
				return shortNameCompare;
			} else {
				if(this.isDefault != other.isDefault){
					if(this.isDefault){
						return -1;
					} else {
						return 1;
					}
				} else {
					if(this.factoryClassName == null && other.factoryClassName == null){
						return 0;
					} else if(other.factoryClassName == null){
						return -1;
					} else if (this.factoryClassName == null){
						return 1;
					} else if(other.factoryClassName.equals(this.overridesFactoryClassName)){
						return -1;
					} else if(this.factoryClassName.equals(other.overridesFactoryClassName)){
						return 1;
					} else {
						return this.factoryClassName.compareTo(other.factoryClassName);
					}	
				}
			}
		}
	}

	protected void addDescriptor(ResourceFactoryDescriptor descriptor) {
		getDescriptors().put(getKey(descriptor), descriptor);
	}
	
	private WTPResourceFactoryRegistryKey []  sortedDescriptors = null;
	
	private WTPResourceFactoryRegistryKey []  getSortedDescriptorKeys() {
		if(sortedDescriptors == null || sortedDescriptors.length != getDescriptors().size()){
			Set keys = getDescriptors().keySet();
			WTPResourceFactoryRegistryKey [] array = new WTPResourceFactoryRegistryKey [keys.size()];
			int count = 0;
			for (Iterator iterator = keys.iterator(); iterator.hasNext();count++) {
				WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) iterator.next();
				array[count] = key;
			}
			Arrays.sort(array, new Comparator<WTPResourceFactoryRegistryKey>() {
				public int compare(WTPResourceFactoryRegistryKey key1,
						WTPResourceFactoryRegistryKey key2) {
					return key1.compareTo(key2);
				}
			});
			sortedDescriptors = array;
		}
		return sortedDescriptors;
	}

	protected synchronized ResourceFactoryDescriptor getDescriptor(URI uri, IContentDescription description) {
		WTPResourceFactoryRegistryKey [] keys = getSortedDescriptorKeys();
		ResourceFactoryDescriptor defaultDescriptor = null;
		
		// first check content type
		if (description != null) {
			for (WTPResourceFactoryRegistryKey key : keys) {
				ResourceFactoryDescriptor descriptor = (ResourceFactoryDescriptor) getDescriptors().get(key);
				
				if ((key.type != null) && (description.getContentType().equals(key.type))) {
					if ((defaultDescriptor == null) || (key.isDefault)) {
						defaultDescriptor = descriptor;
					}
				}
			}
		}
		
		// then check short name, overriding default if necessary
		for (WTPResourceFactoryRegistryKey key : keys) {
			ResourceFactoryDescriptor descriptor = (ResourceFactoryDescriptor) getDescriptors().get(key);
						
			if ((key.shortName != null) && (uri.lastSegment().equals(key.shortName))) {
				if ((defaultDescriptor == null) 
						|| ((description == null) && (key.isDefault))) {
					defaultDescriptor = descriptor;
				}
			}
		}
		
		return defaultDescriptor;
	}
	
	private URI newPlatformURI(URI aNewURI, IProject project) {
		
		if (project == null)
			return ModuleURIUtil.trimToDeployPathSegment(aNewURI);
		try {
			IVirtualComponent component = ComponentCore.createComponent(project);

			URI deployPathSegment = ModuleURIUtil.trimToDeployPathSegment(aNewURI);
			
			//IVirtualFile newFile = component.getFile(new Path(deployPathSegment.path()));			
			IVirtualFolder rootFolder = component.getRootFolder();
			IVirtualFile newFile = rootFolder.getFile(new Path(deployPathSegment.path()));
			
			return URI.createPlatformResourceURI(newFile.getWorkspaceRelativePath().toString());
			 
		} catch(Exception e) {
			ModulecorePlugin.logError(e);
		}
		return null;
	}
	
	private IContentDescription getDescriptionFromURI(URI uri) {
		String contentTypeIdentifier = ModuleURIUtil.getContentTypeName(uri);
		if (contentTypeIdentifier != null)
			return Platform.getContentTypeManager().getContentType(contentTypeIdentifier).getDefaultDescription();
		else
			return null;
		
	}

	protected synchronized ResourceFactoryDescriptor getDescriptor(URI uri) {
		IFile file = WorkbenchResourceHelper.getPlatformFile(uri);
		IContentDescription description = null;
		if (file != null && file.exists()) {
			try {
				description = file.getContentDescription();
			} catch (CoreException e) {
				ModulecorePlugin.logError(e);
			}
		}
		if (description == null) {//Check for optional embedded uri segment, then normalize
			description = getDescriptionFromURI(uri);
			try {
				if (description != null) {
					IProject componentProject = null;
					try {
						componentProject = StructureEdit.getContainingProject(uri);
					} catch (UnresolveableURIException e) {
						ModulecorePlugin.logError(e);
					}
					uri = PlatformURLModuleConnection.resolve(uri);
					uri = newPlatformURI(uri,componentProject);
				} 
			} catch (IOException e) {
				ModulecorePlugin.logError(e);
			}
		}
		
		ResourceFactoryDescriptor defaultDesc = getDescriptor(uri, description);
		// Ok no content type match - go to super
		if (defaultDesc != null){
			return defaultDesc;
		}
		else{
			return super.getDescriptor(uri);
		}
	}

	public Factory getFactory(URI uri, String contentType) {
		IContentType type = Platform.getContentTypeManager().getContentType(contentType);
		if (type != null)
			return getFactory(uri, type.getDefaultDescription());
		return super.getFactory(uri, contentType);
	}
	
	
	/**
	 *  Returns true if the uri is found in the WTPResourceFactoryRegistry descriptor.
	 *  This will not load any extension points
	 */
	public synchronized boolean shortNameRegistered(URI uri) {
		Map m = getDescriptors();
		Collection c = m.values();
		Iterator iter = c.iterator();
		String uriLastSegment = uri.lastSegment();
		while(iter.hasNext()) {
			ResourceFactoryDescriptor descriptor = (ResourceFactoryDescriptor) iter.next();
			if(descriptor.getShortSegment() != null && descriptor.getShortSegment().equals(uriLastSegment)) {
				return true;
			}
		}
		return false;
	}
}
