/*******************************************************************************
 * 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;
	private boolean javaElementChangeListenerIsActive;
	
	
	// ********** 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();
		this.javaElementChangeListenerIsActive = true;
	}


	// ********** 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);
	}

	/**
	 * Return whether the model manager's Java change listener is active.
	 */
	public boolean javaElementChangeListenerIsActive() {
		return this.javaElementChangeListenerIsActive;
	}

	/**
	 * Set whether the model manager's Java change listener is active.
	 */
	public void setJavaElementChangeListenerIsActive(boolean javaElementChangeListenerIsActive) {
		this.javaElementChangeListenerIsActive = javaElementChangeListenerIsActive;
	}

	/**
	 * 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;
			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_(delta);
		this.checkForOpenedProject(project, delta);
	}


	/**
	 * Checked exceptions bite.
	 */
	private void projectChanged_(IResourceDelta delta) {
		try {
			this.jpaModel.projectChanged(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.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.REMOVED :  // already handled with the PRE_DELETE event
				break;
			case IResourceDelta.CHANGED : 
				this.checkDeltaFlagsForOpenedProject(project, delta);
				break;
			case IResourceDelta.ADDED_PHANTOM :  // ignore
				break;
			case IResourceDelta.REMOVED_PHANTOM :  // ignore
				break;
			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.javaElementChangeListenerIsActive) {
			return;  // ignore Java events
		}
		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$
	}

}
