/*******************************************************************************
 * Copyright (c) 2005 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.List;

import org.eclipse.core.resources.IProject;
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.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.JavaModelException;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
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 ((flags & IJavaElementDelta.F_CHILDREN) == IJavaElementDelta.F_CHILDREN) {
				if (element instanceof IJavaModel) {
					final IJavaElementDelta[] children = delta.getChangedChildren();
					for (int i = 0; i < children.length; i++) {
						// handle all of the IJavaProject children
						processJavaElementDelta(children[i]);
					}					
				} else if (element instanceof IJavaProject
						&& (flags & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0) {
					final IJavaProject jproject = (IJavaProject) element;
					final IProject project = jproject.getProject();
					// make certain this is a J2EE project
					if (ModuleCoreNature.getModuleCoreNature(project) != null) {
						try {
							alterMapping(delta.getAffectedChildren(), jproject, project);
						} catch (CoreException ce) {
							Logger.getLogger().logError(ce);
						}
					}
				}
			}
		}
	}

	/*
	 * Adds or removes a resource mapping from the .component file.
	 */
	private void alterMapping(final IJavaElementDelta[] children, final IJavaProject jproject,
			final IProject project) throws CoreException {
		List pathsToAdd = null;
		List pathsToRemove = null;
		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) {
					// 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
					int flags = delta.getFlags();
					if (delta.getKind() == IJavaElementDelta.ADDED || 
							(flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) == IJavaElementDelta.F_ADDED_TO_CLASSPATH) {
						if (!abortAdd) {
							if(pathsToAdd == null){
								pathsToAdd = new ArrayList();
							}
							final IPath path = root.getPath().removeFirstSegments(1);
							pathsToAdd.add(path);
							// 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();
								if(pathsToRemove == null){
									pathsToRemove = new ArrayList();
								}
								pathsToRemove.add(movedFromElement.getPath().removeFirstSegments(1));
							}
						}
					// getting a kind = REMOVED and flags = 0 for removal of the folder (w/o removing the CPE), probably
				    // should not be generated
					} else if ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) == IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) {
						if(pathsToRemove == null){
							pathsToRemove = new ArrayList();
						}
						IPath path = root.getPath().removeFirstSegments(1);
						pathsToRemove.add(path);
					}
				}
			}
		}
		if(pathsToAdd != null || pathsToRemove != null){
			final List jobPathsToAdd = pathsToAdd;
			final List jobPathsToRemove = pathsToRemove;
			WorkspaceJob job = new WorkspaceJob("J2EEComponentMappingUpdateJob") {							
				public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
					IVirtualFolder destFolder = getDestinationFolder(project);
					IPath path = null;
					if(jobPathsToAdd != null){
						for(int i=0;i<jobPathsToAdd.size(); i++){
							path = (IPath)jobPathsToAdd.get(i);
							destFolder.createLink(path, 0, monitor);
						}
					}
					if(jobPathsToRemove != null){
						for(int i=0;i<jobPathsToRemove.size(); i++){
							path = (IPath)jobPathsToRemove.get(i);
							destFolder.removeLink(path, 0, monitor);
						}
					}
					return Status.OK_STATUS;
				}
				public boolean belongsTo(final Object family) {
					return PROJECT_COMPONENT_UPDATE_JOB_FAMILY.equals(family);
				}
			};
			job.setRule(ResourcesPlugin.getWorkspace().getRoot());
			job.schedule();
		}
	}
	
	

	/*
	 * Retrieves the IVirtualFolder to which Java src folders should be mapped
	 */
	private IVirtualFolder getDestinationFolder(final IProject project) throws CoreException {
		final IVirtualComponent c = ComponentCore.createComponent(project);
		c.create(0, null);
		final IVirtualFolder root = c.getRootFolder();
		if (J2EEProjectUtilities.isDynamicWebProject(project)) {
			// web projects map to WEB-INF/classes
			return root.getFolder(new Path(J2EEConstants.WEB_INF_CLASSES));
		}
		// all other J2EE project types (that are Java projects) map 
		// Java src folders to the project root
		return root;
	}
	
}
