/*******************************************************************************
 * Copyright (c) 2005, 2007 BEA Systems, Inc.
 * 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:
 * rfrost@bea.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.refactor.listeners;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;

/**
 * Implementation of <code>IElementChangedListener that updates mappings for src folders
 * in the .component file in response to changes in a project's Java classpath. 
 */
public class J2EEElementChangedListener implements IElementChangedListener {

	/**
	 * Name of the Job family in which all component update jobs belong.
	 */
	public static final String PROJECT_COMPONENT_UPDATE_JOB_FAMILY =  "org.eclipse.jst.j2ee.refactor.component"; //$NON-NLS-1$
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
	 */
	public void elementChanged(final ElementChangedEvent event) {
		processJavaElementDelta(event.getDelta());
	}
	
	private void processJavaElementDelta(final IJavaElementDelta delta) {
		final int kind = delta.getKind();
		if (kind == IJavaElementDelta.CHANGED) {
			final int flags = delta.getFlags();
			final IJavaElement element = delta.getElement();
			if (element instanceof IJavaModel) {
				if ((flags & IJavaElementDelta.F_CHILDREN) == IJavaElementDelta.F_CHILDREN) {
					final IJavaElementDelta[] children = delta.getChangedChildren();
					for (int i = 0; i < children.length; i++) {
						// handle all of the IJavaProject children
						processJavaElementDelta(children[i]);
					}
				} else {
					// not a Java project (i.e. could be an EAR project)
					processResourceDeltas(flags, kind, delta);
				}
			} else if (element instanceof IJavaProject) {
				processJavaProject((IJavaProject) element, flags, kind, delta);
			}
		}
	}
	
	private void processJavaProject(final IJavaProject jproject, final int flags, final int kind, final IJavaElementDelta delta) {

		final IProject project = jproject.getProject();
		final List pathsToAdd = new ArrayList();
		final List pathsToRemove = new ArrayList();
		final List changedJavaPaths = new ArrayList();
		
		// make certain this is a J2EE project
		if (ModuleCoreNature.isFlexibleProject(project)) {
			IVirtualComponent c = ComponentCore.createComponent(project);
			if(c == null)
				return;
			try {
				// Did the classpath change?
				if ((flags & IJavaElementDelta.F_CHILDREN) == IJavaElementDelta.F_CHILDREN) {
					final boolean cpChanged = (flags & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0; 
					getJavaSrcMappings(c, delta.getAffectedChildren(), cpChanged, jproject, pathsToAdd, pathsToRemove, changedJavaPaths);
				}

				// Did a non-Java folder change name?
				final IResourceDelta[] deltas = delta.getResourceDeltas();
				if (deltas != null && deltas.length > 0) {
					getNonJavaFolderMappings(deltas, c, pathsToAdd, pathsToRemove, changedJavaPaths);
				}
		
			} catch (CoreException ce) {
				J2EEPlugin.logError(ce);
				return;
			}
			updateMappingsInJob(pathsToAdd, pathsToRemove);
		}		
	}
	
	private void processResourceDeltas(final int flags, final int kind, final IJavaElementDelta delta) {
		final List pathsToAdd = new ArrayList();
		final List pathsToRemove = new ArrayList();

		final IResourceDelta[] deltas = delta.getResourceDeltas();
		if (deltas != null && deltas.length > 0) {
			try {
				getNonJavaFolderMappings(deltas, null, pathsToAdd, pathsToRemove, Collections.EMPTY_LIST);
			} catch (CoreException ce) {
				J2EEPlugin.logError(ce);
				return;
			}
		}
		
		updateMappingsInJob(pathsToAdd, pathsToRemove);
	}
	
	/*
	 * Adds and removes the specified component resource mappings in a WorkspaceJob
	 */
	private void updateMappingsInJob(final List pathsToAdd, final List pathsToRemove) {
		// If there are corrections to the virtual path mappings, execute them in a Job
		if (!pathsToAdd.isEmpty() || !pathsToRemove.isEmpty()) {
			WorkspaceJob job = new WorkspaceJob(RefactorMessages.J2EEElementChangedListener_J2EE_Component_Mapping_Update_) {							
				@Override
				public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
					for(int i=0;i<pathsToAdd.size(); i++){
						Object[] toAdd = (Object[]) pathsToAdd.get(i);
						final IVirtualFolder destFolder = (IVirtualFolder) toAdd[1];
						final IPath pathToAdd = (IPath) toAdd[0];
						destFolder.createLink(pathToAdd, 0, monitor);
					}
					for(int i=0;i<pathsToRemove.size(); i++){
						Object[] toRemove = (Object[]) pathsToRemove.get(i);
						final IVirtualFolder destFolder = (IVirtualFolder) toRemove[1];
						final IPath pathToRemove = (IPath) toRemove[0];
						destFolder.removeLink(pathToRemove, 0, monitor);
					}
					return Status.OK_STATUS;
				}
				@Override
				public boolean belongsTo(final Object family) {
					return PROJECT_COMPONENT_UPDATE_JOB_FAMILY.equals(family);
				}
			};
			job.setRule(ResourcesPlugin.getWorkspace().getRoot());
			job.setSystem(true);
			job.schedule();
		}						
	}
	
	/*
	 * Computes the virtual component path mapping changes the need to be made due to 
	 * Java src path changes.
	 */ 
	private void getJavaSrcMappings(final IVirtualComponent virtualComp, final IJavaElementDelta[] children, final boolean cpChanged, final IJavaProject jproject, final List pathsToAdd, final List pathsToRemove, final List changedPaths) 
		throws CoreException {
		
		// get the default destination folder
		final IVirtualFolder defaultDestFolder = getDestinationFolder(virtualComp);
		
		for (int i = 0; i < children.length; i++) {
			final IJavaElementDelta delta = children[i];
			final IJavaElement element = delta.getElement();
			if(element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT){
				final IPackageFragmentRoot root = (IPackageFragmentRoot) element;
				int cpeKind = IPackageFragmentRoot.K_SOURCE;
				boolean abortAdd = false;
				try {
					cpeKind = root.getKind();
				} catch (JavaModelException jme) {
					// this is thrown if the folder corresponding to the CPE has been deleted
					// since it could represent another error, we need to abort adding. 
					abortAdd = true;
				}
				// only update if we know it is a src folder
				if (cpeKind == IPackageFragmentRoot.K_SOURCE) {
					final int kind = delta.getKind();					
					if (!cpChanged) {
						// if the classpath is not changed, save modifications to the Java src path
						if (kind == IJavaElementDelta.CHANGED || kind == IJavaElementDelta.REMOVED) {
							changedPaths.add(root.getPath().removeFirstSegments(1));		
						}
					} else {
					
						// kind and flags for CP additions are somewhat sporadic; either:
						// -kind is ADDED and flags are 0
						//   or
						// -kind is CHANGED and flags are F_ADDED_TO_CLASSPATH
						final int flags = delta.getFlags();

						if (kind == IJavaElementDelta.ADDED || 
								(flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) == IJavaElementDelta.F_ADDED_TO_CLASSPATH) {
							if (!abortAdd) {
								final IPath pathToAdd = root.getPath().removeFirstSegments(1);
								pathsToAdd.add(new Object[]{pathToAdd, defaultDestFolder});
								// if the added src path was moved from another location, remove any mapping for that
								// location
								if ((flags & IJavaElementDelta.F_MOVED_FROM) == IJavaElementDelta.F_MOVED_FROM) {
									final IJavaElement movedFromElement = delta.getMovedFromElement();
									final IPath pathToRemove = movedFromElement.getPath().removeFirstSegments(1);
									pathsToRemove.add(new Object[]{pathToRemove, defaultDestFolder});
								}
							}
							// getting a kind = REMOVED and flags = 0 for removal of the folder (w/o removing the CPE), probably
							// should not be generated
						} else if (kind == IJavaElementDelta.REMOVED || (flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) == IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) {
							IPath path = root.getPath().removeFirstSegments(1);
							pathsToRemove.add(new Object[]{path, defaultDestFolder});
						} 
					}			
				}
			}
		}
	}
	
	/*
	 * Computes the virtual component path mapping changes the need to be made due to changes to
	 * non-Java folders. 
	 */ 
	private void getNonJavaFolderMappings(final IResourceDelta[] deltas, final IVirtualComponent virtualComp, final List pathsToAdd, final List pathsToRemove, final List changedJavaPaths) throws CoreException {
		IVirtualFolder rootFolder = null;
		if (virtualComp != null) {
			rootFolder = virtualComp.getRootFolder();
		}
		Map sourceToRuntime = null;
		if (virtualComp != null) {
			sourceToRuntime = getResourceMappings(virtualComp.getProject());
		}
		for (int i = 0; i < deltas.length; i++) {
			final IResourceDelta delta = deltas[i];
			processResourceDelta(delta, rootFolder, sourceToRuntime, pathsToAdd, pathsToRemove, changedJavaPaths);
		}
	}
	
	/*
	 * Processes a single IResourceDelta.
	 */
	private void processResourceDelta(final IResourceDelta delta, IVirtualFolder rootFolder, Map sourceToRuntime, final List pathsToAdd, final List pathsToRemove, final List changedJavaPaths) throws CoreException {
		IVirtualFolder localRootFolder = rootFolder;
		Map localSourceToRuntime = sourceToRuntime;
		final int kind = delta.getKind();
		if (kind == IResourceDelta.CHANGED) {
			IResourceDelta[] childDeltas = delta.getAffectedChildren();
			for (int i = 0; i < childDeltas.length; i++) {
				processResourceDelta(childDeltas[i], localRootFolder, localSourceToRuntime, pathsToAdd, pathsToRemove, changedJavaPaths);
			}
		} else if (kind == IResourceDelta.REMOVED){
			if(sourceToRuntime != null){
				IResource resource = delta.getResource();
				if(resource.getType() == IResource.FOLDER){
					IVirtualComponent c = ComponentCore.createComponent(resource.getProject());
					if(c != null){
						localRootFolder = c.getRootFolder();
						final IPath movedFrom = delta.getProjectRelativePath();
						final IPath runtimePath = (IPath) sourceToRuntime.get(movedFrom);
						final IVirtualFolder folder = rootFolder.getFolder(runtimePath);
						pathsToRemove.add(new Object[]{movedFrom, folder});
					}
				}
			}
		} else {
			final int flags = delta.getFlags();
			if ((flags & IResourceDelta.MOVED_FROM) == IResourceDelta.MOVED_FROM) {
				if (localRootFolder == null) {
					final IProject project = delta.getResource().getProject();
					// make certain this is a J2EE project
					if (ModuleCoreNature.getModuleCoreNature(project) != null) {
						IVirtualComponent c = ComponentCore.createComponent(project);
						localRootFolder = c.getRootFolder();
						localSourceToRuntime = getResourceMappings(project);
					} else {
						// not a J2EE project
						return;
					}
				}
				final IPath movedFrom = delta.getMovedFromPath().removeFirstSegments(1);
				if (changedJavaPaths.contains(movedFrom)) {
					// don't update renamed Java src paths
					return;
				}
				final IPath movedTo = delta.getFullPath().removeFirstSegments(1);
				final IPath runtimePath = (IPath) localSourceToRuntime.get(movedFrom);
				// does the old path have a virtual component mapping?
				if (runtimePath != null) {
					final IVirtualFolder folder = localRootFolder.getFolder(runtimePath);
					// only add if the project relative paths are not equal (these can be equal when the root folder is mapped and the project is renamed)
					if (!movedFrom.equals(movedTo)) {
						pathsToRemove.add(new Object[]{movedFrom, folder});
						pathsToAdd.add(new Object[]{movedTo, folder});
					}
				}
			}
		}
	}
	
	private Map getResourceMappings(final IProject project){
		final Map sourceToRuntime = new HashMap();
		StructureEdit core = null;
		try {
			core = StructureEdit.getStructureEditForRead(project);
			final WorkbenchComponent component = core.getComponent();
			if (null != component) {
				final List currentResources = component.getResources();
				for (Iterator iter = currentResources.iterator(); iter.hasNext();) {
					final ComponentResource resource = (ComponentResource) iter.next();
					sourceToRuntime.put(resource.getSourcePath().makeRelative(), resource.getRuntimePath());
				}
			}
		} catch (NullPointerException e) {
			J2EEPlugin.logError(e);
		} finally {
			if (core != null)
				core.dispose();
		}
		return sourceToRuntime;
	}

	/*
	 * Retrieves the IVirtualFolder to which Java src folders should be mapped
	 */
	private IVirtualFolder getDestinationFolder(final IVirtualComponent c) throws CoreException {
		final IVirtualFolder root = c.getRootFolder();
		
		if( JavaEEProjectUtilities.usesJavaEEComponent(c )){
			if (JavaEEProjectUtilities.isDynamicWebProject(c.getProject())) {
				return root.getFolder(new Path(J2EEConstants.WEB_INF_CLASSES));
			}
			return root;
		}
		//get source folders
		List<IPath> srcFolders = getSourceFolders(c.getProject());
		//get existing deploy mappings
		Map mapping = getResourceMappings(c.getProject());
		IPath deployPath = null;
		
		//if existing source folder has mapping set for this one
		for( IPath srcFolder : srcFolders )
		{
			if( mapping.containsKey(srcFolder) ){
				deployPath = (IPath)mapping.get(srcFolder);
				if( deployPath == null )
					return root;
				return root.getFolder(deployPath);
			}
		}
		return root;
	}
	
	protected static List<IPath> getSourceFolders(IProject project) {
		
		IJavaProject javaProj = JavaCore.create(project);
		if (javaProj == null)
			return null;
		if( !javaProj.exists() )
			return null;
		
		IClasspathEntry[] cp = null;
		try {
			cp = javaProj.getRawClasspath();
		} catch (JavaModelException ex) {
			J2EEPlugin.logError(ex);
			return null;
		}
		List sourcePaths = new ArrayList();
		for (int i = 0; i < cp.length; i++) {
			if (cp[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				sourcePaths.add(cp[i].getPath().removeFirstSegments(1));
			}
		}
		return sourcePaths;
	}
	
}
