/*******************************************************************************
 * Copyright (c) 2003, 2012 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.jst.j2ee.internal.common.classpath;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

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.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.common.jdt.internal.classpath.FlexibleProjectContainer;
import org.eclipse.jst.j2ee.application.internal.operations.IModuleExtensions;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.componentcore.util.EARVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentHelper;
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.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.javaee.application.Application;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraphListener;
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraphUpdateEvent;
import org.eclipse.wst.common.componentcore.internal.impl.ResourceTreeRootAdapter;
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.internal.emf.utilities.ExtendedEcoreUtil;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;

public class J2EEComponentClasspathUpdater implements IResourceChangeListener, IResourceDeltaVisitor, IDependencyGraphListener {

	private static J2EEComponentClasspathUpdater instance = null;

	private static boolean suspendPostChangeEvents = false;

	private static boolean updateDependencyGraph = true;

	private int pauseCount = 0;
	
	public static IPath WEB_APP_LIBS_PATH = new Path("org.eclipse.jst.j2ee.internal.web.container"); //$NON-NLS-1$

	public static J2EEComponentClasspathUpdater getInstance() {
		if (instance == null) {
			init();
		}
		return instance;
	}

	private static void init() {
		if (instance == null) {
			instance = new J2EEComponentClasspathUpdater();
		}
	}

	/**
	 * Pauses updates; any caller of this method must ensure through a
	 * try/finally block that resumeUpdates is subsequently called.
	 */
	public void pauseUpdates() {
		synchronized (this) {
			pauseCount++;
		}
	}

	public void resumeUpdates() {
		resumeUpdates(true);
	}
	
	private void resumeUpdates(boolean scheduleJob){
		synchronized (this) {
			if (pauseCount > 0) {
				pauseCount--;
			}
			if (pauseCount > 0) {
				return;
			}
		}
		if(scheduleJob){
			moduleUpdateJob.schedule(MODULE_UPDATE_DELAY);
		}
	}
	
	public void forceUpdate(Collection projects){
		forceUpdate(projects, true);
	}
	
	/**
	 * Collection of type IProject
	 * @param projects
	 */
	public void forceUpdate(Collection projects, boolean runAsJob) {
		try {
			pauseUpdates();
			Iterator iterator = projects.iterator();
			while(iterator.hasNext()){
				queueUpdate((IProject)iterator.next());
			}
		} finally {
			forceUpdateOnNextRun = true;
			// the following code is in place of the normal call to
			// resume updates.  This restores the pauseCount and forces 
			// the job to be scheduled immediately 
			synchronized (this) {
				if (pauseCount > 0) {
					pauseCount--;
				}
			}
			if(runAsJob){
				moduleUpdateJob.schedule(0);
			} else {
				try
				{
					updateDependencyGraph = false;
					moduleUpdateJob.run(new NullProgressMonitor());
				}
				finally
				{
					updateDependencyGraph = true;
				}
			}
		}
	}
	
	private boolean forceUpdateOnNextRun = false;
	
	public void queueUpdate(IProject project) {
		if (J2EEProjectUtilities.isEARProject(project)) {
			queueUpdateEAR(project);
		} else if (J2EEProjectUtilities.isApplicationClientProject(project) || J2EEProjectUtilities.isEJBProject(project) || J2EEProjectUtilities.isDynamicWebProject(project)
				|| J2EEProjectUtilities.isJCAProject(project) || J2EEProjectUtilities.isUtilityProject(project)) {
			queueUpdateModule(project);
		}
	}

	public void queueUpdateModule(IProject project) {
		moduleUpdateJob.queueModule(project);
		synchronized (this) {
			if (pauseCount > 0) {
				return;
			}
		}
		moduleUpdateJob.schedule(MODULE_UPDATE_DELAY);
	}

	public void queueUpdateEAR(IProject earProject) {
		moduleUpdateJob.queueEAR(earProject);
		synchronized (this) {
			if (pauseCount > 0) {
				return;
			}
		}
		moduleUpdateJob.schedule(MODULE_UPDATE_DELAY);
	}
	
	public boolean projectsQueued() {
		return moduleUpdateJob.projectsQueued() || moduleUpdateJob.getState() != Job.NONE;
	}
	
	private static final int MODULE_UPDATE_DELAY = 30;
	public static final String MODULE_UPDATE_JOB_NAME = "EAR Libraries Update Job"; 

	private final ModuleUpdateJob moduleUpdateJob = new ModuleUpdateJob();

	public class ModuleUpdateJob extends Job {

		public boolean belongsTo(Object family) {
			if(family == MODULE_UPDATE_JOB_NAME){
				return true;
			}
			return super.belongsTo(family);
		}
		
		// We use the listener list as a thread safe queue.
		private class Queue extends ListenerList  {
			public synchronized Object[] getListeners() {
				Object[] data = super.getListeners();
				clear();
				return data;
			}
		};

		private Queue moduleQueue = new Queue();

		private Queue earQueue = new Queue();

		//a private queue for adding modules queued by the EAR
		private Queue earAddedModuleQueue = new Queue();
		
		public ModuleUpdateJob() {
			super(MODULE_UPDATE_JOB_NAME); 
			setRule(ResourcesPlugin.getWorkspace().getRoot());
			setSystem(true);
		}

		public void queueEAR(IProject ear) {
			earQueue.add(ear);
		}

		public void queueModule(IProject project) {
			moduleQueue.add(project);
		}
		
		public boolean projectsQueued() {
			return !earQueue.isEmpty() || !moduleQueue.isEmpty();
		}

		/**
		 * Add referenced EARs from the queued modules into the EARs queue
		 */
		private void queueReferencingEars(Object[] projects) {
			for (int p = 0; p < projects.length; p++) {
				IProject project = (IProject) projects[p];
				if (!isKnown(project)) {
					IProject[] earProjects = J2EEProjectUtilities.getReferencingEARProjects(project);
					for (int i = 0; i < earProjects.length; i++) {
						queueEAR(earProjects[i]);
					}
				} 
			}
		}
		
		private void processEars() {
			Object[] earProjects = earQueue.getListeners();
			for (int i = 0; i < earProjects.length; i++) {
				IProject earProject = (IProject) earProjects[i];
				if (J2EEProjectUtilities.isEARProject(earProject))
				{
					IVirtualComponent earComponent = ComponentCore.createComponent(earProject); 
					IVirtualReference[] refs = J2EEProjectUtilities.getComponentReferences(earComponent);
					IVirtualComponent comp = null;
					for (int j = 0; j < refs.length; j++) {
						comp = refs[j].getReferencedComponent();
						if (!comp.isBinary()) {
							earAddedModuleQueue.add(comp.getProject());
						}
					}
					if(null != earComponent){
						JavaEEBinaryComponentHelper.clearDisconnectedArchivesInEAR(earComponent);	
					}
				}
			}
		}
		
		private void processModules(Object[] projects) {
			for (int i = 0; i < projects.length; i++) {
				IProject project = (IProject) projects[i];
				// this block is for Web app Libraries
				if (J2EEProjectUtilities.isDynamicWebProject(project)) {
					IClasspathContainer webAppLibrariesContainer = J2EEComponentClasspathContainerUtils.getInstalledWebAppLibrariesContainer(project);
					// If the container is present, refresh it
					if (webAppLibrariesContainer != null) {
						((FlexibleProjectContainer) webAppLibrariesContainer).refresh();
					}
				}

				// ******************** The following is for EAR Libraries
				IClasspathContainer earLibrariesContainer = J2EEComponentClasspathContainerUtils.getInstalledEARLibrariesContainer(project);
				// If the container is present, refresh it
				if (earLibrariesContainer != null) {
					((J2EEComponentClasspathContainer) earLibrariesContainer).refresh(forceUpdateOnNextRun);
				}
			}
			// [202820]
			updateDependencyGraph = true;
		}
		
		protected IStatus run(IProgressMonitor monitor) {

			SafeRunner.run(new ISafeRunnable() {
				public void handleException(Throwable e) {
					J2EEPlugin.getDefault().getLogger().logError(e);
				}

				public void run() throws Exception {
					try {
						Object[] moduleProjects = moduleQueue.getListeners();
						queueReferencingEars(moduleProjects);
						processEars();
						Object [] earQueuedModuleProjects = earAddedModuleQueue.getListeners();
						Set modulesSet = new HashSet();
						modulesSet.addAll(Arrays.asList(moduleProjects));
						modulesSet.addAll(Arrays.asList(earQueuedModuleProjects));
						Object [] modulesArray = modulesSet.toArray();
						processModules(modulesArray);
					} finally {
						forceUpdateOnNextRun = false;
					}
					
				}
			});

			return Status.OK_STATUS;
		}
	};

	public IClasspathContainer getWebAppLibrariesContainer(IProject webProject, boolean create) {
		IJavaProject jproj = JavaCore.create(webProject);
		IClasspathContainer container = null;
		IClasspathEntry entry = create ? null : getExistingContainer(jproj, WEB_APP_LIBS_PATH);
		if (entry != null || create) {
		try {
				container = JavaCore.getClasspathContainer(WEB_APP_LIBS_PATH, jproj);
		} catch (JavaModelException e) {
				J2EEPlugin.getDefault().getLogger().logError(e);
		}
	}
		return container;
	}
	
	/**
	 * Returns the existing classpath container if it is already on the classpath. This will not
	 * create a new container.
	 * 
	 * @param jproj
	 * @param classpathContainerID
	 * @return
	 */
	public IClasspathEntry getExistingContainer(IJavaProject jproj, IPath classpathContainerPath) {
		return J2EEComponentClasspathContainerUtils.getInstalledContainerEntry(jproj, classpathContainerPath);
	}

	private Set knownProjects = new HashSet();
	
	private boolean isKnown(IProject project){
		return !knownProjects.add(project.getName());
	}
	
	private void forgetProject(IProject project){
		knownProjects.remove(project.getName());
	}
	
	public void dependencyGraphUpdate(IDependencyGraphUpdateEvent event) {
		if((event.getType() & IDependencyGraphUpdateEvent.ADDED) == IDependencyGraphUpdateEvent.ADDED){
			Map<IProject, Set<IProject>> addedReferences = event.getAddedReferences();
			for(IProject referencedProject : addedReferences.keySet()){
				queueUpdate(referencedProject);
			}
		}
	}
	
	public void resourceChanged(IResourceChangeEvent event) {
		boolean scheduleJob = false;
		try {
			pauseUpdates();
			switch (event.getType()){
				case IResourceChangeEvent.PRE_CLOSE:
				case IResourceChangeEvent.PRE_DELETE:
					IResource resource = event.getResource();
					if(resource.getType() == IResource.PROJECT){
						if(ModuleCoreNature.isFlexibleProject((IProject) resource)){
							if(J2EEProjectUtilities.isEARProject((IProject)resource)){
								IProject earProject = (IProject) resource;
								
								IVirtualReference[] refs = J2EEProjectUtilities.getComponentReferences(ComponentCore.createComponent(earProject));
								IVirtualComponent comp = null;
								for (int j = 0; j < refs.length; j++) {
									comp = refs[j].getReferencedComponent();
									if (!comp.isBinary()) {
										queueUpdateModule(comp.getProject());
									}
								}
									
							} else {
								IProject[] earProjects = J2EEProjectUtilities.getReferencingEARProjects((IProject)resource);
								for(int i=0; i<earProjects.length; i++){
									queueUpdateEAR(earProjects[i]);
								}
							}
							forgetProject((IProject)resource);
						}
						JavaEEBinaryComponentHelper.clearAllArchivesInProject((IProject)resource);
					}
					break;
				case IResourceChangeEvent.POST_CHANGE:
					if(!suspendPostChangeEvents) {
						scheduleJob = true;
						event.getDelta().accept(this);
						IResourceDelta[] d = event.getDelta().getAffectedChildren();
						findNode(d);
					}
					break;
			}
		} catch (CoreException e) {
			J2EEPlugin.getDefault().getLogger().logError(e);
		} 
		finally {
			resumeUpdates(scheduleJob);
		}
	}
	

	public static void clearResourceTreeRootCache(WorkbenchComponent aModule) {

		ResourceTreeRootAdapter resourceTreeAdapter = (ResourceTreeRootAdapter) ExtendedEcoreUtil
				.getAdapter(aModule, aModule.eAdapters(),
						ResourceTreeRootAdapter.DEPLOY_ADAPTER_TYPE);
		if(null != resourceTreeAdapter) {
			resourceTreeAdapter.setResourceTreeRoot(null);
		}
		resourceTreeAdapter = (ResourceTreeRootAdapter) ExtendedEcoreUtil
				.getAdapter(aModule, aModule.eAdapters(),
						ResourceTreeRootAdapter.SOURCE_ADAPTER_TYPE);
		if(null != resourceTreeAdapter){
			resourceTreeAdapter.setResourceTreeRoot(null);
		}
	}


	/*
	 * Needs to notice changes to MANIFEST.MF in any J2EE projects, changes to
	 * .component in any J2EE Projects, and any archive changes in EAR projects
	 */
	
	public boolean findNode(IResourceDelta[] delta) {

		for (int i = 0; i < delta.length; i++) {
			if (delta[i].toString().indexOf(IJ2EEModuleConstants.COMPONENT_FILE_NAME) != -1) {
				StructureEdit core = StructureEdit
						.getStructureEditForRead(delta[i].getResource()
								.getProject());
				if(null != core){
					WorkbenchComponent component = core.getComponent();
					if(component != null){
						clearResourceTreeRootCache(component);
					}
				}
			} else {
				findNode(delta[i].getAffectedChildren());
			}
		}

		return true;
	}
	
	public boolean visit(IResourceDelta delta) {
		// If it is only a marker change, ignore the change
		if(delta.getFlags() == IResourceDelta.MARKERS) {
			return false;
		}
		
		IResource resource = delta.getResource();
		switch (resource.getType()) {
		case IResource.ROOT:
			return true;
		case IResource.PROJECT:
			return ModuleCoreNature.isFlexibleProject((IProject) resource);
		case IResource.FOLDER: {
			if (resource.getName().equals(IJ2EEModuleConstants.DOT_SETTINGS)) {
				return true;
			}
			IVirtualComponent comp = ComponentCore.createComponent(resource.getProject());

			if (comp instanceof J2EEModuleVirtualComponent || comp instanceof EARVirtualComponent) {
				IVirtualFolder rootFolder = comp.getRootFolder();
				if (comp instanceof EARVirtualComponent) {
					return isRootAncester(resource, rootFolder) || isEARLibraryDirectory(resource, comp);
				} else { // J2EEModuleVirtualComponent
					return isRootAncester(resource, rootFolder) || isFolder(resource, rootFolder.getFolder(J2EEConstants.META_INF));
				}
			}
			return false;
		}
		case IResource.FILE: {
			String name = resource.getName();
			if (name.equals(WTPModulesResourceFactory.WTP_MODULES_SHORT_NAME)) {
				queueUpdate(resource.getProject());
			} else if (name.equals(J2EEConstants.MANIFEST_SHORT_NAME)) { // MANIFEST.MF must be all caps per spec
				IFile manifestFile = J2EEProjectUtilities.getManifestFile(resource.getProject(), false);
				if (null == manifestFile || resource.equals(manifestFile)) {
					queueUpdateModule(resource.getProject());
				}
			} else if (endsWithIgnoreCase(name, IModuleExtensions.DOT_JAR) || endsWithIgnoreCase(name, ".zip")) {
				try {
					if (FacetedProjectFramework.hasProjectFacet(resource.getProject(), J2EEProjectUtilities.ENTERPRISE_APPLICATION)) {
						IVirtualComponent comp = ComponentCore.createComponent(resource.getProject());
						if(isFolder(resource.getParent(), comp.getRootFolder()) || isEARLibraryDirectory(resource, comp)){
							queueUpdateEAR(resource.getProject());
						}
					}
				} catch (CoreException e) {
					J2EEPlugin.getDefault().getLogger().logError(e);
				}
			}
		}
		default:
			return false;
		}
	}
	
	private boolean isEARLibraryDirectory(IResource resource, IVirtualComponent earComponent) {
		// check if the EAR component's version is 5 or greater
		IProject project = earComponent.getProject();
		if (!JavaEEProjectUtilities.isJEEComponent(earComponent, JavaEEProjectUtilities.DD_VERSION)
				|| !JavaEEProjectUtilities.isJEEComponent(earComponent, JavaEEProjectUtilities.FACET_VERSION)) {
			return false;
		}
		
		// retrieve the model provider
		IModelProvider modelProvider = ModelProviderManager.getModelProvider(project);
		if (modelProvider == null) return false;
		
		// retrieve the EAR's model object
		Application app = (Application) modelProvider.getModelObject();
		if (app == null) return false;
		
		// retrieve the library directory from the model
		String libDir = app.getLibraryDirectory();
		if (libDir == null) {
			// the library directory is not set - use the default one
			libDir = J2EEConstants.EAR_DEFAULT_LIB_DIR;
		}
		
		IVirtualFolder libFolder = earComponent.getRootFolder().getFolder(libDir); 
		if(resource.getType() == IResource.FILE){
			return isRootAncester(resource.getParent(), libFolder);
		}
		return isRootAncester(resource, libFolder);
	}

	public static boolean endsWithIgnoreCase(String str, String sfx) {
		return str.regionMatches(true, str.length() - sfx.length(), sfx, 0, sfx.length());
	}

	public static boolean isFolder(IResource resource, IVirtualFolder folder) {
		IContainer[] realFolders = folder.getUnderlyingFolders();
		for (int i = 0; i < realFolders.length; i++) {
			if (realFolders[i].equals(resource)) {
				return true;
			}
		}
		return false;
	}

	public static boolean isRootAncester(IResource resource, IVirtualFolder rootFolder) {
		IContainer[] realRoots = rootFolder.getUnderlyingFolders();
		IPath currentResourcePath = resource.getFullPath();
		for (int i = 0; i < realRoots.length; i++) {
			if (currentResourcePath.isPrefixOf(realRoots[i].getFullPath()))
				return true;
		}
		return false;
	}

	public static boolean shouldUpdateDependencyGraph()
	{
		return updateDependencyGraph;
	}
	
	// [202820]
	public static void setUpdateDependencyGraph(boolean value)
	{
		updateDependencyGraph = value;
	}
	
	public void setSuspendPostChangeEvents(boolean suspendAction) {
		J2EEComponentClasspathUpdater.suspendPostChangeEvents = suspendAction;
	}

	public boolean isSuspendPostChangeEvents() {
		return suspendPostChangeEvents;
	}
}
