package org.eclipse.jst.j2ee.internal.common;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.impl.WTPModulesResourceFactory;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;

public class J2EEDependencyListener implements IResourceChangeListener, IResourceDeltaVisitor {

	public static J2EEDependencyListener INSTANCE = new J2EEDependencyListener();
	
	private Object lock = new Object();
	
	private long modStamp = 0;
	
	private J2EEDependencyListener() {
	}

	public long getModStamp(){
		synchronized (lock) {
			return modStamp;
		}
	}
	
	private void incrementModStamp(){
		synchronized (lock){
			modStamp++;
		}
	}
	
	private List<IProject> cachedEARModuleDependencies = new ArrayList<IProject>();

	private void cacheModuleDependencies(IProject earProject) {
		if (EarUtilities.isEARProject(earProject)) {
			IVirtualReference[] refs = EarUtilities.getComponentReferences(ComponentCore.createComponent(earProject));
			IVirtualComponent comp = null;
			for (int j = 0; j < refs.length; j++) {
				comp = refs[j].getReferencedComponent();
				if (!comp.isBinary()) {
					cachedEARModuleDependencies.add(comp.getProject());
				}
			}
		}
	}

	/**
	 * returns whether the modStamp has been updated
	 * @return
	 */
	private boolean updateModuleDependencies() {
		if (!cachedEARModuleDependencies.isEmpty()) {
			incrementModStamp();
			cachedEARModuleDependencies.clear();
			return true;
		}
		return false;
	}

	private long modStampAtResourceChanged = 0;
	public void resourceChanged(IResourceChangeEvent event) {
		try {
			switch (event.getType()) {
			case IResourceChangeEvent.PRE_CLOSE:
			case IResourceChangeEvent.PRE_DELETE:
				IResource resource = event.getResource();
				if (resource.getType() == IResource.PROJECT) {
					cacheModuleDependencies((IProject) resource);
				}
				break;
			case IResourceChangeEvent.POST_CHANGE:
				modStampAtResourceChanged = getModStamp();
				event.getDelta().accept(this);
			}
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		}
	}

	public boolean visit(IResourceDelta delta) throws CoreException {
		if(modStampAtResourceChanged != getModStamp()){
			//already incremented the modification stamp, no need to continue
			return false;
		}
		IResource resource = delta.getResource();
		switch (resource.getType()) {
		case IResource.ROOT:
			return true;
		case IResource.PROJECT:
			int kind = delta.getKind();
			if ((IResourceDelta.ADDED & kind) != 0) {
				// if an EAR project is added then all dependent modules must be
				// updated
				if (EarUtilities.isEARProject((IProject) resource)) {
					cacheModuleDependencies((IProject) resource);
					updateModuleDependencies();
				}
				return false;
			} else if ((IResourceDelta.REMOVED & kind) != 0) {
				updateModuleDependencies();
				return false;
			} else if ((IResourceDelta.CHANGED & kind) != 0) {
				int flags = delta.getFlags();
				if ((IResourceDelta.OPEN & flags) != 0) {
					boolean isOpen = ((IProject) resource).isOpen();
					if (isOpen) {
						// if an EAR project is open all dependent modules must
						// be updated
						cacheModuleDependencies((IProject) resource);
					}
					// this will also pickup both close and open events
					// if the EAR project is closed, the cached dependent
					// modules will already
					if(updateModuleDependencies()){
						return false;
					}
				}
				return true;
			}
			return false;
		case IResource.FOLDER:
			return true;
		case IResource.FILE:
			String name = resource.getName();
			// MANIFEST.MF must be all caps per spec
			if (name.equals(J2EEConstants.MANIFEST_SHORT_NAME)) {
				IFile manifestFile = J2EEProjectUtilities.getManifestFile(resource.getProject(), false);
				if (null == manifestFile || resource.equals(manifestFile)) {
					incrementModStamp();
				}
			} else if (name.equals(WTPModulesResourceFactory.WTP_MODULES_SHORT_NAME)) {
				if (EarUtilities.isEARProject(resource.getProject())) {
					incrementModStamp();
				}
			} else if (endsWithIgnoreCase(name, IJ2EEModuleConstants.JAR_EXT) || endsWithIgnoreCase(name, IJ2EEModuleConstants.WAR_EXT) || endsWithIgnoreCase(name, IJ2EEModuleConstants.RAR_EXT)) {
				if (EarUtilities.isEARProject(resource.getProject())) {
					IVirtualComponent comp = ComponentCore.createComponent(resource.getProject());
					if (isInTree((IFile)resource, comp.getRootFolder())) {
						incrementModStamp();
					}
				}
			}
		}
		return false;
	}

	public static boolean isInTree(IFile file, IVirtualFolder folder) {
		// If we are the folder, return true
		if( isFolder(file.getParent(), folder))
				return true;
		
		// if resource is any level under current VF's underlying folders, return true 
		IContainer[] underlying = folder.getUnderlyingFolders();
		for( int i = 0; i < underlying.length; i++ ) {
			if( underlying[i].getFullPath().isPrefixOf(file.getFullPath()))
				return true;
		}
		
		// continue to peruse in case there's some odd mapping, such as 
		// /EarConten5 -> /my/secret/location/wherever/it/goes
		boolean found = false;
		try {
			IVirtualResource[] children = folder.members();
			for(int i = 0; i < children.length && !found; i++ ) {
				if( children[i].getType() == IVirtualResource.FOLDER) {
					found |= isInTree(file, (IVirtualFolder)children[i]);
				}
			}
		} catch( CoreException ce) {
			J2EEPlugin.logError(ce);
		}
		return found;
	}
	
	public static boolean endsWithIgnoreCase(String str, String sfx) {
		return J2EEComponentClasspathUpdater.endsWithIgnoreCase(str, sfx);

	}

	public static boolean isFolder(IResource resource, IVirtualFolder folder) {
		return J2EEComponentClasspathUpdater.isFolder(resource, folder);
	}
}
