/*******************************************************************************
 * Copyright (c) 2006, 2008 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.core.internal;

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.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
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.IOpenable;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jpt.core.JpaFile;
import org.eclipse.jpt.core.JpaModel;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.utility.internal.BitTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;

/**
 * "Internal" global stuff.
 * Provide access via a singleton.
 * Hold and manage the JPA model (which holds all the JPA projects)
 * and the various global listeners. We attempt to determine whether events
 * are relevant before forwarding them to the JPA model.
 * 
 * Various things that cause us to add or remove a JPA project:
 * - Startup of the Dali plug-in will trigger all the JPA projects to be added
 * 
 * - Project created and facet installed
 *     facet POST_INSTALL
 * - Project facet uninstalled
 *     facet PRE_UNINSTALL
 * 
 * - Project opened
 *     facet PROJECT_MODIFIED
 * - Project closed
 *     facet PROJECT_MODIFIED
 * 
 * - Pre-existing project imported from directory or archive (created and opened)
 *     resource POST_CHANGE -> PROJECT -> ADDED -> OPEN
 * - Project deleted
 *     resource PRE_DELETE
 * 
 * - Project facet installed by editing the facets settings file directly
 *     facet PROJECT_MODIFIED
 * - Project facet uninstalled by editing the facets settings file directly
 *     facet PROJECT_MODIFIED
 */
public class JpaModelManager {

	/**
	 * The JPA model - null until the plug-in is started.
	 */
	private GenericJpaModel jpaModel;

	/**
	 * Listen for changes to projects and files.
	 */
	private final IResourceChangeListener resourceChangeListener;

	/**
	 * Listen for the JPA facet being added or removed from a project.
	 */
	private final IFacetedProjectListener facetedProjectListener;

	/**
	 * Listen for Java changes and forward them to the JPA model,
	 * which will forward them to the JPA projects.
	 */
	private final IElementChangedListener javaElementChangeListener;
	
	
	// ********** singleton **********

	private static final JpaModelManager INSTANCE = new JpaModelManager();

	/**
	 * Return the singleton JPA model manager.
	 */
	public static JpaModelManager instance() {
		return INSTANCE;
	}


	// ********** constructor **********

	/**
	 * Private - ensure single instance.
	 */
	private JpaModelManager() {
		super();
		this.resourceChangeListener = new ResourceChangeListener();
		this.facetedProjectListener = new FacetedProjectListener();
		this.javaElementChangeListener = new JavaElementChangeListener();
	}


	// ********** plug-in controlled life-cycle **********

	/**
	 * internal - called by JptCorePlugin
	 */
	public synchronized void start() throws Exception {
		debug("*** START JPA model manager ***"); //$NON-NLS-1$
		try {
			this.jpaModel = new GenericJpaModel();
			ResourcesPlugin.getWorkspace().addResourceChangeListener(
				this.resourceChangeListener, 
				IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.POST_BUILD);
			FacetedProjectFramework.addListener(this.facetedProjectListener, IFacetedProjectEvent.Type.values());
			JavaCore.addElementChangedListener(this.javaElementChangeListener);
		} catch (RuntimeException ex) {
			this.log(ex);
			this.stop();
		}
	}

	/**
	 * internal - called by JptCorePlugin
	 */
	public synchronized void stop() throws Exception {
		debug("*** STOP JPA model manager ***"); //$NON-NLS-1$
		JavaCore.removeElementChangedListener(this.javaElementChangeListener);
		FacetedProjectFramework.removeListener(this.facetedProjectListener);
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this.resourceChangeListener);
		this.jpaModel.dispose();
		this.jpaModel = null;
	}


	// ********** API **********

	/**
	 * Return the workspace-wide JPA model.
	 */
	public JpaModel getJpaModel() {
		return this.jpaModel;
	}

	/** 
	 * Return the JPA project corresponding to the specified Eclipse project,
	 * or null if unable to associate the specified project with a
	 * JPA project.
	 */
	public JpaProject getJpaProject(IProject project) throws CoreException {
		return this.jpaModel.getJpaProject(project);
	}

	/**
	 * Return the JPA file corresponding to the specified Eclipse file,
	 * or null if unable to associate the specified file with a JPA file.
	 */
	public JpaFile getJpaFile(IFile file) throws CoreException {
		return this.jpaModel.getJpaFile(file);
	}

	/**
	 * The JPA settings associated with the specified Eclipse project
	 * have changed in such a way as to require the associated
	 * JPA project to be completely rebuilt
	 * (e.g. when the user changes a project's JPA platform).
	 */
	public void rebuildJpaProject(IProject project) {
		this.jpaModel.rebuildJpaProject(project);
	}

	/**
	 * Log the specified status.
	 */
	public void log(IStatus status) {
		JptCorePlugin.log(status);
    }

	/**
	 * Log the specified message.
	 */
	public void log(String msg) {
		JptCorePlugin.log(msg);
    }

	/**
	 * Log the specified exception or error.
	 */
	public void log(Throwable throwable) {
		JptCorePlugin.log(throwable);
	}


	// ********** resource changed **********

	/**
	 * Check for:
	 *   - project close/delete
	 *   - file add/remove
	 *   - project open/rename
	 */
	/* private */ void resourceChanged(IResourceChangeEvent event) {
		// build events can have the workspace or project as source
		if (event.getType() == IResourceChangeEvent.POST_BUILD) {
			this.resourcePostBuild(event);
			return;
		}
		
		if (! (event.getSource() instanceof IWorkspace)) {
			return;  // this probably shouldn't happen...
		}
		
		switch (event.getType()) {
			case IResourceChangeEvent.PRE_DELETE :  // project-only event
				this.resourcePreDelete(event);
				break;
			case IResourceChangeEvent.POST_CHANGE :
				this.resourcePostChange(event);
				break;
			// we do not listen to these event types
			// case IResourceChangeEvent.PRE_CLOSE :  // project-only event
			// case IResourceChangeEvent.PRE_BUILD :
			default :
				break;
		}
		
		
	}

	/**
	 * A project is being deleted. Remove its corresponding
	 * JPA project if appropriate.
	 */
	private void resourcePreDelete(IResourceChangeEvent event) {
		IProject project = (IProject) event.getResource();
		debug("Resource (Project) PRE_DELETE: ", project); //$NON-NLS-1$
		this.jpaModel.projectPreDelete(project);
	}

	/**
	 * A resource has changed somehow.
	 * Check for files being added or removed.
	 * (The JPA project only handles added and removed files here
	 * Changed files are handlded via the Java Element Changed event.)
	 * Also check for opened projects.
	 */
	private void resourcePostChange(IResourceChangeEvent event) {
		debug("Resource POST_CHANGE"); //$NON-NLS-1$
		this.resourceChanged(event.getDelta());
	}

	private void resourceChanged(IResourceDelta delta) {
		IResource resource = delta.getResource();
		switch (resource.getType()) {
			case IResource.ROOT :
				this.resourceChangedChildren(delta);
				break;
			case IResource.PROJECT :
				this.projectChanged((IProject) resource, delta);
				break;
			case IResource.FILE :
			case IResource.FOLDER :
			default :
				break;
		}
	}

	private void resourceChangedChildren(IResourceDelta delta) {
		for (IResourceDelta child : delta.getAffectedChildren()) {
			this.resourceChanged(child);  // recurse
		}
	}

	private void projectChanged(IProject project, IResourceDelta delta) {
		this.projectChanged_(project, delta);
		this.checkForOpenedProject(project, delta);
	}


	/**
	 * Checked exceptions bite.
	 */
	private void projectChanged_(IProject project, IResourceDelta delta) {
		try {
			this.jpaModel.projectChanged(project, delta);
		} catch (CoreException ex) {
			this.log(ex);  // problem traversing the project's resources - not much we can do
		}
	}

	/**
	 * Crawl the specified delta, looking for projects being opened.
	 * Projects being deleted are handled in IResourceChangeEvent.PRE_DELETE.
	 * Projects being closed are handled in IFacetedProjectEvent.Type.PROJECT_MODIFIED.
	 */
	private void checkForOpenedProject(IProject project, IResourceDelta delta) {
		switch (delta.getKind()) {
			case IResourceDelta.CHANGED : 
				this.checkDeltaFlagsForOpenedProject(project, delta);
				break;
			case IResourceDelta.REMOVED :  // already handled with the PRE_DELETE event
			case IResourceDelta.ADDED :  // all but project import and rename handled with the facet POST_INSTALL event
				this.checkDeltaFlagsForOpenedProject(project, delta);
				this.checkDeltaFlagsForRenamedProject(project, delta);
				break;
			case IResourceDelta.ADDED_PHANTOM :  // ignore
			case IResourceDelta.REMOVED_PHANTOM :  // ignore
			default :
				break;
		}
	}

	/**
	 * We don't get any events from the Facets Framework when a pre-existing
	 * project is imported, so we need to check for the newly imported project here.
	 * 
	 * This event also occurs when a project is simply opened. Project opening
	 * also triggers a Facet PROJECT_MODIFIED event and that is where we add
	 * the JPA project, not here
	 */
	private void checkDeltaFlagsForOpenedProject(IProject project, IResourceDelta delta) {
		if (BitTools.flagIsSet(delta.getFlags(), IResourceDelta.OPEN) && project.isOpen()) {
			debug("\tProject CHANGED - OPEN: ", project.getName()); //$NON-NLS-1$
			this.jpaModel.checkForTransition(project);
		}
	}
	
	/**
	 * We don't get any events from the Facets Framework when a project is renamed,
	 * so we need to check for the renamed projects here.
	 */
	private void checkDeltaFlagsForRenamedProject(IProject project, IResourceDelta delta) {
		if (BitTools.flagIsSet(delta.getFlags(), IResourceDelta.MOVED_FROM) && project.isOpen()) {
			debug("\tProject ADDED - MOVED_FROM: ", delta.getMovedFromPath()); //$NON-NLS-1$
			this.jpaModel.checkForTransition(project);
		}
	}
	
	/**
	 * A post build event has occurred.
	 * Check for whether the build was a "clean" build and trigger project update.
	 */
	private void resourcePostBuild(IResourceChangeEvent event) {
		debug("Resource POST_BUILD"); //$NON-NLS-1$
		if (event.getBuildKind() == IncrementalProjectBuilder.CLEAN_BUILD) {
			this.resourcePostClean(event.getDelta());
		}
	}
	
	private void resourcePostClean(IResourceDelta delta) {
		IResource resource = delta.getResource();
		switch (resource.getType()) {
			case IResource.ROOT :
				this.resourcePostCleanChildren(delta);
				break;
			case IResource.PROJECT :
				this.projectPostClean((IProject) resource);
				break;
			case IResource.FILE :
			case IResource.FOLDER :
			default :
				break;
		}
	}
	
	private void resourcePostCleanChildren(IResourceDelta delta) {
		for (IResourceDelta child : delta.getAffectedChildren()) {
			this.resourcePostClean(child);  // recurse
		}
	}
	
	private void projectPostClean(IProject project) {
		JpaProject jpaProject = null;
		try {
			jpaProject = getJpaProject(project);
		}
		catch (CoreException ce) {
			// nothing to do, we won't be able to update anyway
		}
		if (jpaProject != null) {
			rebuildJpaProject(project);
		}
	}
	
	
	// ********** faceted project changed **********

	/**
	 * Check for:
	 *   - install of JPA facet
	 *   - un-install of JPA facet
	 *   - any other appearance or disappearance of the JPA facet
	 */
	/* private */ void facetedProjectChanged(IFacetedProjectEvent event) {
		switch (event.getType()) {
			case POST_INSTALL :
				this.facetedProjectPostInstall((IProjectFacetActionEvent) event);
				break;
			case PRE_UNINSTALL :
				this.facetedProjectPreUninstall((IProjectFacetActionEvent) event);
				break;
			case PROJECT_MODIFIED :
				this.facetedProjectModified(event.getProject().getProject());
				break;
			default :
				break;
		}
	}

	private void facetedProjectPostInstall(IProjectFacetActionEvent event) {
		debug("Facet POST_INSTALL: ", event.getProjectFacet()); //$NON-NLS-1$
		if (event.getProjectFacet().getId().equals(JptCorePlugin.FACET_ID)) {
			this.jpaModel.jpaFacetedProjectPostInstall(event);
		}
	}

	private void facetedProjectPreUninstall(IProjectFacetActionEvent event) {
		debug("Facet PRE_UNINSTALL: ", event.getProjectFacet()); //$NON-NLS-1$
		if (event.getProjectFacet().getId().equals(JptCorePlugin.FACET_ID)) {
			this.jpaModel.jpaFacetedProjectPreUninstall(event);
		}
	}

	/**
	 * This event is triggered for any change to a faceted project.
	 * We use the event to watch for the following:
	 *   - an open project is closed
	 *   - a closed project is opened
	 *   - one of a project's (facet) metadata files is edited directly
	 */
	private void facetedProjectModified(IProject project) {
		debug("Facet PROJECT_MODIFIED: ", project.getName()); //$NON-NLS-1$
		this.jpaModel.checkForTransition(project);
	}


	// ********** Java element changed **********

	/**
	 * Forward the event to the JPA model.
	 */
	/* private */ void javaElementChanged(ElementChangedEvent event) {
		if (this.eventIndicatesProjectAddedButNotOpen(event)) {
			return;
		}
		this.jpaModel.javaElementChanged(event);
	}

	//209275 - This particular event only causes problems in a clean workspace the first time a JPA project
	//is created through the JPA wizard. The second time a JPA project is created, this event occurs, but 
	//it occurs as the wizard is closing so it does not cause a deadlock.
	private boolean eventIndicatesProjectAddedButNotOpen(ElementChangedEvent event) {
		IJavaElementDelta delta = event.getDelta();
		if (delta.getKind() == IJavaElementDelta.CHANGED) {
			if (delta.getElement().getElementType() == IJavaElement.JAVA_MODEL) {
				IJavaElementDelta[] children = delta.getAffectedChildren();
				if (children.length == 1) {
					IJavaElementDelta childDelta = children[0];
					if (childDelta.getKind() == IJavaElementDelta.ADDED) {
						IJavaElement childElement = childDelta.getElement();
						if (childElement.getElementType() == IJavaElement.JAVA_PROJECT) {
							if (childDelta.getAffectedChildren().length == 0) {
								if (!((IOpenable) childElement).isOpen()) {
									return true;
								}
							}
						}
					}
				}
			}
		}	
		return false;
	}
	
	
	// ********** resource change listener **********

	/**
	 * Forward the Resource change event back to the JPA model manager.
	 */
	private class ResourceChangeListener implements IResourceChangeListener {
		ResourceChangeListener() {
			super();
		}
		public void resourceChanged(IResourceChangeEvent event) {
			JpaModelManager.this.resourceChanged(event);
		}
		@Override
		public String toString() {
			return StringTools.buildToStringFor(this);
		}
	}


	// ********** faceted project listener **********

	/**
	 * Forward the Faceted project change event back to the JPA model manager.
	 */
	private class FacetedProjectListener implements IFacetedProjectListener {
		FacetedProjectListener() {
			super();
		}
		public void handleEvent(IFacetedProjectEvent event) {
			JpaModelManager.this.facetedProjectChanged(event);
		}
		@Override
		public String toString() {
			return StringTools.buildToStringFor(this);
		}
	}


	// ********** Java element change listener **********

	/**
	 * Forward the Java element change event back to the JPA model manager.
	 */
	private class JavaElementChangeListener implements IElementChangedListener {
		JavaElementChangeListener() {
			super();
		}
		public void elementChanged(ElementChangedEvent event) {
			JpaModelManager.this.javaElementChanged(event);
		}
		@Override
		public String toString() {
			return StringTools.buildToStringFor(this);
		}
	}
	
	
	// ********** debug **********

	// @see JpaModelTests#testDEBUG()
	private static final boolean DEBUG = false;

	/**
	 * trigger #toString() call and string concatenation only if DEBUG is true
	 */
	private static void debug(String message, Object object) {
		if (DEBUG) {
			debug_(message + object);
		}
	}

	private static void debug(String message) {
		if (DEBUG) {
			debug_(message);
		}
	}

	private static void debug_(String message) {
		System.out.println(Thread.currentThread().getName() + ": " + message); //$NON-NLS-1$
	}

}
