/*******************************************************************************
 * Copyright (c) 2005, 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
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jee.model.internal;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.jem.util.emf.workbench.FlexibleProjectResourceSet;
import org.eclipse.jem.util.emf.workbench.ProjectResourceSet;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jst.j2ee.componentcore.EnterpriseArtifactEdit;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.IModelProviderEvent;
import org.eclipse.jst.j2ee.model.IModelProviderListener;
import org.eclipse.jst.j2ee.model.ModelProviderEvent;
import org.eclipse.jst.javaee.core.internal.util.JavaeeResourceImpl;
import org.eclipse.jst.jee.JEEPlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.impl.PlatformURLModuleConnection;
import org.eclipse.wst.common.componentcore.internal.impl.WTPResourceFactoryRegistry;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateInputProvider;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidator;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorImpl;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorPresenter;

public class JEE5ModelProvider implements IModelProvider, ResourceStateInputProvider, ResourceStateValidator, IModelProviderListener{

	protected XMLResourceImpl writableResource;
	protected IProject proj;
	protected IPath defaultResourcePath;
	protected ResourceStateValidator stateValidator;
	protected ResourceAdapter resourceAdapter = new ResourceAdapter();
	protected final ListenerList listeners = new ListenerList();
	//private static boolean resourceChangeListenerEnabled = false;

	private List modelResources = new ArrayList();
	protected class ResourceAdapter extends AdapterImpl {
		@Override
		public void notifyChanged(Notification notification) {
			if (notification.getEventType() == Notification.SET
					&& notification.getFeatureID(null) == Resource.RESOURCE__IS_LOADED) {
				resourceIsLoadedChanged((Resource) notification.getNotifier(), notification.getOldBooleanValue(), notification.getNewBooleanValue());
			} else if (notification.getFeatureID(null) == Resource.RESOURCE__IS_MODIFIED)
				resourceChanged((Resource) notification.getNotifier());
		}
		@Override
		public boolean equals(Object arg0) {
			
			return this.getClass().equals(arg0.getClass());
		}

		@Override
		public int hashCode() {
			
			return getClass().hashCode();
		}
	}
	
	public JEE5ModelProvider() {
		super();
	}

	protected ProjectResourceSet getResourceSet(IProject proj2) {
		return (ProjectResourceSet)WorkbenchResourceHelperBase.getResourceSet(proj);
	}

	public XMLResourceImpl getWritableResource() {
		return writableResource;
	}

	public void setWritableResource(XMLResourceImpl writableResource) {
		this.writableResource = writableResource;
	}
	
	protected void resourceChanged(Resource aResource) {
		if (hasListeners()) {
			int eventCode = ModelProviderEvent.KNOWN_RESOURCES_CHANGED;
			ModelProviderEvent evt = new ModelProviderEvent(eventCode, this, proj);
			evt.addResource(aResource);
			notifyListeners(evt);
		}
	}
	
	protected void resourceIsLoadedChanged(Resource aResource, boolean oldValue, boolean newValue) {
		if (hasListeners()) {
			int eventCode = newValue ? ModelProviderEvent.LOADED_RESOURCE : ModelProviderEvent.UNLOADED_RESOURCE;
			ModelProviderEvent evt = new ModelProviderEvent(eventCode, this, proj);
			evt.addResource(aResource);
			notifyListeners(evt);
		}
	}
	private synchronized void addManagedResource(XMLResourceImpl res) {
		if (res == null || modelResources.contains(res)) {
			return;
		}
		URI uri = res.getURI();
		for (Iterator iterator = modelResources.iterator(); iterator.hasNext();) {
			XMLResourceImpl resource = (XMLResourceImpl) iterator.next();
			if (resource == null) {
				iterator.remove();
				continue;
			}
			if (resource.getURI() != null && resource.getURI().equals(uri)) {
				resource.eAdapters().remove(resourceAdapter);
				iterator.remove();
			}
		}
		modelResources.add(res);
		if (!res.eAdapters().contains(resourceAdapter))
			res.eAdapters().add(resourceAdapter);
	}
	/**
	 * Returns true if there are any listeners
	 */
	public boolean hasListeners() {
		return !listeners.isEmpty();
	}
	
	private URI getModuleURI(URI uri) {
		URI moduleuri = ModuleURIUtil.fullyQualifyURI(proj,getContentTypeDescriber());
		IPath requestPath = new Path(moduleuri.path()).append(new Path(uri.path()));
		URI resourceURI = URI.createURI(PlatformURLModuleConnection.MODULE_PROTOCOL + requestPath.toString());
		return resourceURI;
	}

	protected XMLResourceImpl getModelResource(final IPath modelPath) {
		if(proj == null || !proj.isAccessible()){
			throw new IllegalStateException("The project <" + proj + "> is not accessible."); //$NON-NLS-1$//$NON-NLS-2$
		}
		if (writableResource != null) {
			addManagedResource(writableResource);
			return writableResource;
		}
		IPath innerModelPath = modelPath;
		if ((innerModelPath == null) || innerModelPath.equals(IModelProvider.FORCESAVE))
			innerModelPath = getDefaultResourcePath();
		ProjectResourceSet resSet = getResourceSet(proj);
		IVirtualFolder container = ComponentCore.createComponent(proj).getRootFolder();
		String modelPathURI = innerModelPath.toString();
		URI uri = URI.createURI(modelPathURI);
		
		IVirtualFile dd = container.getFile(innerModelPath);
		URI projURI = URI.createURI(dd.getProjectRelativePath().toString());
		
		XMLResourceImpl res = null;
		try {
			if (dd.exists()) {
				res = (XMLResourceImpl) resSet.getResource(getModuleURI(uri),true);
				addManagedResource(res);
			} else {//First find in resource set, then create if not found new Empty Resource.
				XMLResourceImpl newRes =  createModelResource(innerModelPath, resSet, projURI);
				addManagedResource(newRes);
				return newRes;
			}
		} catch (WrappedException ex) {
			if (ex.getCause() instanceof FileNotFoundException)
				return null;
			throw ex;
		}
		return res;
	}
	

	protected XMLResourceImpl createModelResource(IPath modelPath, ProjectResourceSet resourceSet, URI uri) {
		// First try to find existing cached resource.
		XMLResourceImpl res = (XMLResourceImpl)resourceSet.getResource(getModuleURI(uri), false);
		if (res == null || !res.isLoaded()) {
			// Create temp resource if no file exists
			res=  (XMLResourceImpl)((FlexibleProjectResourceSet)resourceSet).createResource(getModuleURI(uri),WTPResourceFactoryRegistry.INSTANCE.getFactory(uri, getContentType(getContentTypeDescriber())));
			res.setEncoding("UTF-8"); //$NON-NLS-1$
			populateRoot(res, resourceSet.getProject().getName());
		}
		return res;
	}

	public void populateRoot(XMLResourceImpl res, String string) {
	}

	private IContentDescription getContentType(String contentTypeDescriber) {
		if (contentTypeDescriber != null)
			return Platform.getContentTypeManager().getContentType(contentTypeDescriber).getDefaultDescription();
		return null;
	}

	public IPath getDefaultResourcePath() {
		return defaultResourcePath;
	}

	public void setDefaultResourcePath(IPath defaultResourcePath) {
		this.defaultResourcePath = defaultResourcePath;
	}

	public Object getModelObject() {
		return getModelObject(getDefaultResourcePath());
	}

	public Object getModelObject(IPath modelPath) {
		return null;
	}
	
	/**
	 * Used to optionally define an associated content type for XML file creation
	 * @return
	 */
	protected String getContentTypeDescriber() {
		
		return null;
	}
	


	public IStatus validateEdit(final IPath modelPath, final Object context) {
		IPath innaerModelPath = modelPath;
		Object innerContext = context;
		if (innaerModelPath == null)
			innaerModelPath = getDefaultResourcePath();
		IWorkspace work = ResourcesPlugin.getWorkspace();
		IFile file = WorkbenchResourceHelper.getFile(getModelResource(innaerModelPath));
		if (file != null && file.exists()) {
			IFile[] files = { file };
			if (innerContext == null)
				innerContext = IWorkspace.VALIDATE_PROMPT;
			return work.validateEdit(files, innerContext);
		}
		return Status.OK_STATUS;
	}

	public void modify(Runnable runnable, IPath modelPath) {
		//About to modify and save this model
		try {
			JavaeeResourceImpl res = (JavaeeResourceImpl)getModelResource(modelPath);
			if (res != null)
				setWritableResource(res);
			runnable.run();
			try {
				if (res != null) {
					if (modelPath != null && modelPath.equals(IModelProvider.FORCESAVE))
						res.save(Collections.EMPTY_MAP,true);
					else
						res.save(Collections.EMPTY_MAP);
				}
			} catch (IOException e) {
				JEEPlugin.logError(e);
			}
		} catch (Exception ex) {
			JEEPlugin.logError(ex);
		} finally {
			setWritableResource(null);
		}
		
	}

//	private class ResourceChangeListener implements IResourceChangeListener {
//		public void resourceChanged(IResourceChangeEvent event) {
//			IResourceDelta delta= event.getDelta();
//			// make sure that there is a delta (since some events don't have one)
//			if (delta != null)
//			{
//				IResourceDelta[] affectedChildren= delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED , IResource.FILE);
//				IResourceDelta projectDelta = null;
//				IResource changedResource = null; 
//				IProject changedProject = null;
//				IPath resourcePath = null;
//
//				for (int i= 0; i < affectedChildren.length; i++) {
//					projectDelta = affectedChildren[i];
//					changedResource = projectDelta.getResource(); 
//					changedProject = changedResource.getProject();
//					HashSet<IPath> currentResources = modelResources.get(changedProject);
//					// only deal with the projects that have resources that have been loaded 
//					if (currentResources != null)
//					{
//						// if this is a project deletion, remove the project from the HashMap.
//						if (changedResource == changedProject && projectDelta.getKind() == IResourceDelta.REMOVED)
//						{
//							modelResources.remove(changedProject);
//							// if modelResources is empty, we should self-destruct
//							if (modelResources.isEmpty())
//							{
//								resourceChangeListenerEnabled = false;
//								ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
//							}
//						}
//						else
//						{
//							Iterator<IPath> iter = currentResources.iterator();
//							ArrayList<IPath> toUnload = new ArrayList<IPath>();
//							// check each resource that was loaded from the project to see if it is part of the change
//							while (iter.hasNext())
//							{
//								resourcePath = iter.next();
//								if (projectDelta.findMember(resourcePath) != null)
//								{
//									// limit the list of resources that need to be unloaded to those that have changed
//									toUnload.add(resourcePath);
//								}
//							}
//							if (toUnload.size() > 0)
//							{
//								Resource current = null;
//								ProjectResourceSet resourceSet = getResourceSet(changedProject);
//								URIConverter uriConverter = resourceSet.getURIConverter();
//								HashSet<URI> resourceURIs = new HashSet<URI>();
//								iter = toUnload.iterator();
//								while (iter.hasNext())
//								{
//									// convert all of the resources to URIs - this is a faster match during the compare
//									resourceURIs.add(uriConverter.normalize(URI.createURI(iter.next().toString())));
//								}
//								Iterator<Resource> iter2 = resourceSet.getResources().iterator();
//								while (iter2.hasNext())
//								{
//									current = iter2.next();
//									if (resourceURIs.contains(current.getURI()))
//									{
//										current.unload();
//									}
//								}
//							}
//						}
//					}
//				}
//			}
//		}
//	}

	public void addListener(IModelProviderListener listener) {
		
		listeners.add(listener);
	}

	public void removeListener(IModelProviderListener listener)
	{
		listeners.remove(listener);
	}
	/**
	 * Save only resources that need to be saved (i.e., no other references).
	 */
	public void modelsChanged(IModelProviderEvent anEvent) {
		int code = anEvent.getEventCode();
		switch (code) {
			case IModelProviderEvent.REMOVED_RESOURCE : {
				if (hasResourceReference(anEvent.getChangedResources()))
					removeResources(anEvent.getChangedResources());
				else
					return;
				break;
			}
		}
		if (hasListeners()) {
			anEvent.setModel(this);
			notifyListeners(anEvent);
		}
	}
	protected void removeResources(List aList) {
		Resource res;
		for (int i = 0; i < aList.size(); i++) {
			res = (Resource) aList.get(i);
			removeResource(res) ;
		}
	}
	/**
	 * Remove reference to the aResource.
	 */
	protected synchronized boolean removeResource(Resource aResource) {
		if (aResource != null) {
			aResource.eAdapters().remove(resourceAdapter);
			return modelResources.remove(aResource);
		}
		return false;
	}
	
	/**
	 * Return true if any Resource in the list of
	 * 
	 * @resources is referenced by me.
	 */
	protected boolean hasResourceReference(List tResources) {
		for (int i = 0; i < tResources.size(); i++) {
			if (hasResourceReference((Resource) tResources.get(i)))
				return true;
		}
		return false;
	}
	/**
	 * Return true if aResource is referenced by me.
	 */
	protected boolean hasResourceReference(Resource aResource) {
		if (aResource != null)
			return getResources().contains(aResource);
		return false;
	}
	
	/**
	 * Notify listeners of
	 * 
	 * @anEvent.
	 */
	protected void notifyListeners(IModelProviderEvent anEvent) {
		
		NotifyRunner notifier = new NotifyRunner(anEvent); 
		
		Object[] notifyList = listeners.getListeners(); 
		for (int i = 0; i < notifyList.length; i++) {
			notifier.setListener( (IModelProviderListener) notifyList[i] );
			SafeRunner.run(notifier);
		}
	}
	public class NotifyRunner implements ISafeRunnable { 
		
		private final IModelProviderEvent event;
		private IModelProviderListener listener;
		
		public NotifyRunner(IModelProviderEvent event) {
			Assert.isNotNull(event);
			this.event = event;
		}
		
		
		public void setListener(IModelProviderListener listener) {
			this.listener = listener;
		}

		public void handleException(Throwable exception) { 
			JEEPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, JEEPlugin.PLUGIN_ID, 0, exception.getMessage(), exception));
			
		}

		public void run() throws Exception {
			if(listener != null)
				listener.modelsChanged(event); 
		}
		
	}
	public ResourceStateValidator getStateValidator() {
		if (stateValidator == null)
			stateValidator = createStateValidator();
		return stateValidator;
	}

	/**
	 * Method createStateValidator.
	 * 
	 * @return ResourceStateValidator
	 */
	private ResourceStateValidator createStateValidator() {
		return new ResourceStateValidatorImpl(this);
	}

	protected EnterpriseArtifactEdit createArtifactEdit() {
		return null;
	}

	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().checkActivation(presenter);
		
	}

	public boolean checkReadOnly() {
		return getStateValidator().checkReadOnly();
	}

	public boolean checkSave(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().checkSave(presenter);
	}

	public void lostActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().lostActivation(presenter);
		
	}

	public IStatus validateState(ResourceStateValidatorPresenter presenter) throws CoreException {
		if (presenter == null)
			return Status.OK_STATUS;
		return getStateValidator().validateState(presenter);
	}

	public void cacheNonResourceValidateState(List roNonResourceFiles) {
		// do nothing
	}

	public List getNonResourceFiles() {
		return null;
	}

	public List getNonResourceInconsistentFiles() {
		return null;
	}

	public synchronized List getResources() {
		return new ArrayList(modelResources);
	}


	public boolean isDirty() {
		
			List list = getResources();
			for (int i = 0; i < list.size(); i++) {
				if (((Resource) list.get(i)).isModified())
					return true;
			}
			return false;
	}
}
