/*
 * Licensed Material - Property of IBM
 * (C) Copyright IBM Corp. 2001, 2005 - All Rights Reserved.
 * US Government Users Restricted Rights - Use, duplication or disclosure
 * restricted by GSA ADP Schedule Contract with IBM Corp.
 */
package org.eclipse.jst.j2ee.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jst.j2ee.internal.common.J2EECommonMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.internal.emf.resource.CompatibilityXMIResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;

public class ModelProviderManager {
	
public static class ModelProviderKey { 
 		
		protected IProjectFacetVersion version;
		protected int priority;
		
		public ModelProviderKey() {
			super();
		}
		@Override
		public boolean equals(Object aOther){
			if( this == aOther )
				return true;
			
			ModelProviderKey otherKey = (ModelProviderKey)aOther;
			if( version.equals( otherKey.version) )
				return true;
			return false;
		}
		
		@Override
		public int hashCode() {
			return version.hashCode();
		}		
	}
private static class ResourceSetListener extends AdapterImpl {
	/*
	 * @see Adapter#notifyChanged(new ENotificationImpl((InternalEObject)Notifier,
	 *      int,(EStructuralFeature) EObject, Object, Object, int))
	 */
	@Override
	public void notifyChanged(Notification notification) {
		switch (notification.getEventType()) {
			case Notification.ADD :
				addedResource((Resource) notification.getNewValue());
				break;
			case Notification.REMOVE :
				removedResource((Resource) notification.getOldValue());
				break;
			case Notification.REMOVE_MANY :
				removedResources((List) notification.getOldValue());
				break;
		}
	}
}
private static WeakHashMap modelsProviders = new WeakHashMap();
private static final int DEFAULT_PRIORITY = 100;
private static HashMap providers;
protected static HashMap resourceSetListeners;

	/**
	 * 
	 * @param 
	 * @param 
	 * @return IModelProvider for the given project of the given version, NULL if no IModelProvider exists for project, version pair
	 */
	public static IModelProvider getModelProvider(IProject project, IProjectFacetVersion vers) {
		
		IModelProviderFactory factory = getProvider(vers);
		if(factory != null){
			startListeningToResourceSet(project);
			return factory.create(project);
		}
		
		String errorMessage = J2EECommonMessages.getResourceString(
				J2EECommonMessages.ERR_NO_MODEL_PROVIDER_FOR_PROJECT, new Object[] {project, vers});
		Throwable error = new NullPointerException(errorMessage);
		
		J2EEPlugin.logError(error);
				
		return null;
	}


	/**
	 * 
	 * @param 
	 * @param 
	 * @return IModelProvider for the given component of the given version, NULL if no IModelProvider exists for virtual component/version pair
	 */
	public static IModelProvider getModelProvider(IVirtualComponent aModule, IProjectFacetVersion vers) {

		IModelProviderFactory factory = getProvider(vers);
		if(factory != null){
			IModelProvider mp = factory.create(aModule);
			addProvider(mp);
			return mp;
		}
		
		String errorMessage = J2EECommonMessages.getResourceString(
				J2EECommonMessages.ERR_NO_MODEL_PROVIDER_FOR_PROJECT, new Object[] {aModule, vers});
		Throwable error = new NullPointerException(errorMessage);
		
		J2EEPlugin.logError(error);
		
		return null;
	}
	
		
		private static void addProvider(IModelProvider mp) {
			modelsProviders.put(mp, null);
			
		}
	
		/**
		 * Notify all editModels of the change.
		 */
		private static void addedResource(Resource addedResource) {
			if ((addedResource != null) && (addedResource instanceof CompatibilityXMIResource))
				((CompatibilityXMIResource) addedResource).setFormat(CompatibilityXMIResource.FORMAT_MOF5);
			IProject proj = WorkbenchResourceHelper.getProject(addedResource);
				IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.ADDED_RESOURCE, null,proj);
				event.addResource(addedResource);
				notifyModelProviders(event);
			
		}
		/**
		 * Notify all editModels of the change.
		 */
		protected static void notifyModelProviders(IModelProviderEvent anEvent) {
		if ((anEvent == null) || (modelsProviders.size() == 0))
				return;
			List aList = new ArrayList();
			synchronized (modelsProviders) {
				aList.addAll(modelsProviders.keySet());
			}
		
		for (int i = 0; i < aList.size(); i++) {
				IModelProvider mod;
				mod = (IModelProvider) aList.get(i);
				try {
					if (mod instanceof IModelProviderListener)
					{
						((IModelProviderListener)mod).modelsChanged(anEvent);
					}
				} catch (Exception e) {
					J2EEPlugin.logError(e);
				}
			}
		}
	
		/**
		 * Notify all editModels of the change.
		 */
		private static void removedResource(Resource removedResource) {
			IProject proj = WorkbenchResourceHelper.getProject(removedResource);
				IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.REMOVED_RESOURCE, null,proj);
				event.addResource(removedResource);
				notifyModelProviders(event);
			
		}
	
		/**
		 * Notify all editModels of the change.
		 */
		private static void removedResources(List removedResources) {
			Resource firstRes = (Resource)removedResources.get(0);
			IProject proj = WorkbenchResourceHelper.getProject(firstRes);
				IModelProviderEvent event = new ModelProviderEvent(IModelProviderEvent.REMOVED_RESOURCE, null,proj);
				event.addResources(removedResources);
				notifyModelProviders(event);
			
		}

	/**
	 * Used to register an IModelProviderFactory against a facet version
	 * 
	 * @param providerFactory
	 *            - {@link IModelProviderFactory}
	 * @param v
	 *            - {@link IProjectFacetVersion}
	 * @param priority
	 *            - {@link String}- Used to allow multiple instances, the
	 *            highest priority is chosen. Priority '0' is higher that
	 *            priority '1'. If priorities are equal the new providerFactory
	 *            is chosen.
	 */
	public static void registerProvider(IModelProviderFactory providerFactory, IProjectFacetVersion v, String priority) {

		int newPriority = (priority != null) ? Integer.parseInt(priority) : DEFAULT_PRIORITY;
		int currentPriority = getProviderPriority(v);
		if (newPriority <= currentPriority) {
			ModelProviderKey key = createProviderKey(v, newPriority);
			getProviders().put(key, providerFactory);
		}
	}

	private static IModelProviderFactory getProvider(IProjectFacetVersion v) {
		Set<ModelProviderKey> keys = getProviders().keySet();
		for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
			ModelProviderKey key = (ModelProviderKey) iterator.next();
			if (key.version.equals(v))
				return (IModelProviderFactory)providers.get(key);
		}
		return null;
	}
	public static IModelProviderFactory getProvider(IProject p) {
		IProjectFacetVersion facetVersion = getDefaultFacet(p);
		return getProvider(facetVersion);
	}
	private static int getProviderPriority(IProjectFacetVersion v) {
		Set<ModelProviderKey> keys = getProviders().keySet();
		for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
			ModelProviderKey key = (ModelProviderKey) iterator.next();
			if (key.version.equals(v))
				return key.priority;
		}
		return DEFAULT_PRIORITY;
	}
	protected static Adapter getResourceSetListener(IProject project) {
		if (resourceSetListeners == null)
			resourceSetListeners = new HashMap();
		Adapter listener = (Adapter)resourceSetListeners.get(project);
		if (listener == null) {
			listener = new ResourceSetListener();
			resourceSetListeners.put(project, listener);
		}
		return listener;
	}

	private static J2EEModelProviderRegistry registry;


	private static void initProviders() {
		//Make sure both variables are null to prevent re-entrant behavior
		if (registry == null && providers == null) {
			providers = new HashMap();
			registry = J2EEModelProviderRegistry.getInstance();
		}
		
	}
	private static void startListeningToResourceSet(IProject project) {
		ResourceSet set = WorkbenchResourceHelper.getResourceSet(project);
		Adapter listener = getResourceSetListener(project);
		if (set != null && !set.eAdapters().contains(listener))
			set.eAdapters().add(listener);
	}
	private static ModelProviderKey createProviderKey(IProjectFacetVersion fv, int priority) {
		ModelProviderKey key =  new ModelProviderKey();
		key.priority = priority;
		key.version = fv;
		return key;
	}

	public static IModelProvider getModelProvider(IProject proj) {
		IProjectFacetVersion facetVersion = getDefaultFacet(proj);
		return getModelProvider(proj, facetVersion);
		
	}

	public static IModelProvider getModelProvider(IVirtualComponent aModule) {
		IProjectFacetVersion facetVersion = getDefaultFacet(aModule);
		return getModelProvider(aModule, facetVersion);		
	}

	private static IProjectFacetVersion getDefaultFacet(IProject proj) {
		String type = J2EEProjectUtilities.getJ2EEProjectType(proj);
		if( ProjectFacetsManager.isProjectFacetDefined(type)) {
			IProjectFacet facet = ProjectFacetsManager.getProjectFacet(type);
			IFacetedProject fp = null;
			try {
				fp = ProjectFacetsManager.create(proj);
			} catch (CoreException e) {
				J2EEPlugin.logError(e);
			}
			if (fp != null && facet != null) {
				return fp.getInstalledVersion(facet);
			}
		}
		return null;
	}

	private static IProjectFacetVersion getDefaultFacet(IVirtualComponent aModule) {
		String type = J2EEProjectUtilities.getJ2EEComponentType(aModule);
		IProjectFacet facet = ProjectFacetsManager.getProjectFacet(type);
		IFacetedProject fp = null;
		try {
			if (aModule.isBinary())
			{
				
			}
			else
			{
				fp = ProjectFacetsManager.create(aModule.getProject());
			}
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		}
		if (fp != null && facet != null) {
			return fp.getInstalledVersion(facet);
		}
		return null;			
	}

	private synchronized static HashMap<ModelProviderKey, IModelProviderFactory> getProviders() {
		if (registry == null)
			initProviders();
		return providers;
	}

}
