/*******************************************************************************
 * 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.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.refactor.RefactorResourceHandler;
import org.eclipse.jst.j2ee.refactor.operations.OptionalRefactorHandler;
import org.eclipse.jst.j2ee.refactor.operations.ProjectRefactorMetadata;
import org.eclipse.jst.j2ee.refactor.operations.ProjectRefactoringDataModelProvider;
import org.eclipse.jst.j2ee.refactor.operations.ProjectRenameDataModelProvider;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraph;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerWorkingCopy;
import org.eclipse.wst.server.core.ServerUtil;

/**
 * Listens for project rename/delete events and, if the project had the
 * ModuleCore nature, executes the appropriate logic to update
 * project references.
  */
public final class ProjectRefactoringListener implements IResourceChangeListener, IResourceDeltaVisitor {
	
	/**
	 * Name of the Job family in which all project rename/delete refactoring jobs belong.
	 */
	public static final String PROJECT_REFACTORING_JOB_FAMILY =  "org.eclipse.jst.j2ee.refactor.project"; //$NON-NLS-1$
	
	/*
	 * Map from name of deleted project to ProjectRefactorMetadata instances.
	 */
	private final Map deletedProjectMetadata = new HashMap();
	
	/**
	 * Maintains a cache of project depencencies;
	 */
	public ProjectRefactoringListener() {
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(final IResourceChangeEvent event) {
		// need to capture PRE_DELETE events so that metadata about the
		// deleted project can be collected and cached
		try {
			if (event.getType() == IResourceChangeEvent.PRE_DELETE) {
				// for now, only dependencies on ModuleCoreNature projects
				final IProject project = (IProject) event.getResource();
                // ensure project is accessible and has both module core and faceted natures
				if (ModuleCoreNature.isFlexibleProject(project)
                        && ProjectFacetsManager.create(project) != null) {
					cacheDeletedProjectMetadata(project);
				}
			} else {
				event.getDelta().accept(this);
			}
		} catch (CoreException ce) {
			J2EEPlugin.logError(ce);
		}
	}
	
	private synchronized void cacheDeletedProjectMetadata(final IProject project) {
		final ProjectRefactorMetadata metadata = new ProjectRefactorMetadata(project, ProjectRefactorMetadata.REFERER_CACHING);
		// precompute the metadata while the project still exists
		metadata.computeMetadata();
		metadata.computeServers();
		Set<IProject> referencingComponents = IDependencyGraph.INSTANCE.getReferencingComponents(project);
		IProject [] referencingProjects = referencingComponents.toArray(new IProject[referencingComponents.size()]);
		metadata.computeDependentMetadata(ProjectRefactorMetadata.REF_CACHING, referencingProjects);
		deletedProjectMetadata.put(project.getName(), metadata);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
	 */
	public boolean visit(final IResourceDelta delta) throws CoreException {
		final IResource resource = delta.getResource();
		if (resource instanceof IWorkspaceRoot) {
			// delta is at the workspace root so keep going
			return true;
		} else if (resource instanceof IProject) {
			processProjectDelta((IProject) resource, delta);
		}
		return false;
	}

	/*
	 * Process the project delta in a sync block.
	 */
	private synchronized void processProjectDelta(final IProject project, final IResourceDelta delta) throws CoreException {
		final int kind = delta.getKind();
		final int flags = delta.getFlags();

		if (kind == IResourceDelta.REMOVED) {
			if (hasDeletedRemovedFlags(flags)) {
				// if the kind is REMOVED and there are no special flags, the project was deleted
				ProjectRefactorMetadata metadata = (ProjectRefactorMetadata) deletedProjectMetadata.remove(project.getName()); 
				// note: only projects with ModuleCoreNature will have cached metadata
				if (metadata != null && OptionalRefactorHandler.getInstance().shouldRefactorDeletedProject(metadata)) {
					//Delete refactoring is now being done by the LTK refactoring framework
					//for all java ee modules. Please refer to JavaEERefactoringParticipant
					//we are only cleaning up the server references here
					updateServerRefs(metadata);
					
				} 
			} 
		} else if (kind == IResourceDelta.ADDED && hasRenamedAddedFlags(flags)) { // was renamed
			// get the original name
			final String originalName = delta.getMovedFromPath().lastSegment();
			//Logger.getLogger().logInfo("Added event for " + originalName + " with flags " + flags);
			// we get PRE_DELETE events on rename so retrieve this
			ProjectRefactorMetadata originalMetadata = (ProjectRefactorMetadata) deletedProjectMetadata.remove(originalName);
			// get the metadata for the new project
			final ProjectRefactorMetadata newMetadata = new ProjectRefactorMetadata(project);
			// note: only projects with ModuleCoreNature will have cached metadata
			if (originalMetadata != null && OptionalRefactorHandler.getInstance().shouldRefactorRenamedProject(originalMetadata)) {
				newMetadata.computeMetadata(originalMetadata.getProject());
				processRename(originalMetadata, newMetadata, delta);
			} 
		} 
	}
	
	/*
	 * Determines if the added project was renamed based on the IResourceDelta flags 
	 */
	private boolean hasRenamedAddedFlags(final int flags) {
		if ((flags & IResourceDelta.DESCRIPTION) > 0
			&& (flags & IResourceDelta.MOVED_FROM) > 0) {
			return true;
		}
		return false;
	}
    
    /*
     * Determines if the removed project was deleted based on the IResourceDelta flags 
     */
    private boolean hasDeletedRemovedFlags(final int flags) {
        if ((flags & IResourceDelta.MOVED_TO) == 0 
                && (flags & IResourceDelta.REPLACED) == 0) {
            return true;
        }
        return false;
    }
	
	/*
	 * Processes the renaming of a project.
	 */
	private void processRename(final ProjectRefactorMetadata originalMetadata, final ProjectRefactorMetadata newMetadata, final IResourceDelta delta) {
		WorkspaceJob job = new WorkspaceJob(RefactorMessages.ProjectRefactoringListener_J2EE_Project_Rename_) {
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
				final IDataModel dataModel = DataModelFactory.createDataModel(new ProjectRenameDataModelProvider());
				dataModel.setProperty(ProjectRefactoringDataModelProvider.PROJECT_METADATA, newMetadata);
                dataModel.setProperty(ProjectRenameDataModelProvider.ORIGINAL_PROJECT_METADATA, originalMetadata);
                dataModel.setProperty(ProjectRenameDataModelProvider.RESOURCE_DELTA, delta);                
				try {
					dataModel.getDefaultOperation().execute(monitor, null);
				} catch (Exception e) {
					final String msg = RefactorResourceHandler.getString("error_updating_project_on_rename", new Object[]{originalMetadata.getProjectName()}); //$NON-NLS-1$
					J2EEPlugin.logError(msg);
					J2EEPlugin.logError(e);
					return new Status(Status.ERROR, J2EEPlugin.PLUGIN_ID, 0, msg, e);
				}				
				return Status.OK_STATUS;
			}
			
			@Override
			public boolean belongsTo(final Object family) {
				return PROJECT_REFACTORING_JOB_FAMILY.equals(family);
			}
		};
		// XXX note: might want to consider switching to a MultiRule for optimization
		job.setRule(ResourcesPlugin.getWorkspace().getRoot());
		job.schedule();
	}
	
	private void updateServerRefs(final ProjectRefactorMetadata refactorMetadata) {
		WorkspaceJob job = new WorkspaceJob("ServerRefreshJob") { //$NON-NLS-1$
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
				final IModule[] modulesToRemove = refactorMetadata.getModules();
				if (modulesToRemove == null || modulesToRemove.length == 0) {
					return Status.OK_STATUS;
				}
				for( int j = 0; j < modulesToRemove.length; j++ ) {
					IServer[] affectedServers = refactorMetadata.getServers(modulesToRemove[j]);
					IServerWorkingCopy wc = null;
					for (int i = 0; i < affectedServers.length; i++) {
						try {
							wc = affectedServers[i].createWorkingCopy();
							List list = Arrays.asList(affectedServers[i].getModules());
							if (list.contains(modulesToRemove[j])) {
								ServerUtil.modifyModules(wc, null, new IModule[]{modulesToRemove[j]}, null);
							}
						} catch (CoreException ce) {
							J2EEPlugin.logError(ce);
						} finally {
							try {
								if (wc != null) {
									wc.saveAll(true, null);
								}
							} catch (CoreException ce) {
								J2EEPlugin.logError(ce);
							}
						}
					}
				}
				return Status.OK_STATUS;
			}
			
			@Override
			public boolean belongsTo(final Object family) {
				return ProjectRefactoringListener.PROJECT_REFACTORING_JOB_FAMILY.equals(family);
			}
		};
		job.setRule(ResourcesPlugin.getWorkspace().getRoot());
		job.schedule();
	}	
	
}