/*******************************************************************************
 * Copyright (c) 2001, 2008 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.validation.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

/**
 * This class manages resource change events for the validation framework.
 */
public class EventManager implements IResourceChangeListener {
	private static EventManager _inst;
	
	// false means that eclipse is not shutting down, and true means that it is shutting down. 
	private boolean _shutdown; 

	private IResourceDeltaVisitor _postAutoBuildVisitor;
	private boolean _isActive; // has the registry been read?
	
	private Set<IProjectChangeListener> _listeners = new CopyOnWriteArraySet<IProjectChangeListener>();

	private EventManager() {
	}

	public static EventManager getManager() {
		if (_inst == null)_inst = new EventManager();
		return _inst;
	}
	
	public void addProjectChangeListener(IProjectChangeListener listener){
		Tracing.log("EventManager-03: add listener: ", listener); //$NON-NLS-1$
		_listeners.add(listener);
	}
	
	public void removeProjectChangeListener(IProjectChangeListener listener){
		_listeners.remove(listener);
	}
	
	private void signal(IProject project, int type){
		if (Tracing.isLogging()){
			String name = "Null"; //$NON-NLS-1$
			if (project != null)name = project.getName();
			Tracing.log("EventManager-02: signal project: " + name + ", IProjectChangeListener type: " + type); //$NON-NLS-1$ //$NON-NLS-2$
		}
		for (IProjectChangeListener pcl : _listeners){
			try {
				pcl.projectChanged(project, type);
			}
			catch (Exception e){
				ValidationPlugin.getPlugin().handleException(e);
			}
		}
	}

	public void opening(IProject project) {
		if (project == null || !ValidationPlugin.isActivated())return;
		
		signal(project, IProjectChangeListener.ProjectOpened);

		// When the project is opened, check for any orphaned tasks or tasks whose owners need to be updated.
//		ConfigurationManager.getManager().opening(project);
	}

	public void closing(IProject project) {
		if (project == null || !ValidationPlugin.isActivated())return;
		
		signal(project, IProjectChangeListener.ProjectClosed);
		
		try {
			boolean isMigrated = ConfigurationManager.getManager().isMigrated(project);
			// If it's not migrated, then it hasn't been loaded, and we don't want to load the
			// validator and its prerequisite plug-ins until they're needed.
			if (isMigrated) {
				ValidatorMetaData[] vmds = ConfigurationManager.getManager().getProjectConfiguration(project).getValidators();
				for (ValidatorMetaData vmd : vmds) {

					if (!vmd.isActive()) {
						// If this validator has not been activated, or if it has been shut down,
						// don't activate it again.
						continue;
					}

					IWorkbenchContext helper = null;
					try {
						helper = vmd.getHelper(project);
						helper.closing();
					} catch (InstantiationException e) {
						// Remove the vmd from the reader's list
						ValidationRegistryReader.getReader().disableValidator(vmd);

						ValidationPlugin.getPlugin().handleException(e);
					} catch (Exception e) {
						// If there is a problem with this particular helper, log the error and
						// continue with the next validator.
						ValidationPlugin.getPlugin().handleException(e);
					}
				}

				ConfigurationManager.getManager().closing(project);
			}
		} catch (InvocationTargetException e) {
			ValidationPlugin.getPlugin().handleException(e);
			if (e.getTargetException() != null)
				ValidationPlugin.getPlugin().handleException(e.getTargetException());
		}
	}

	public void deleting(IProject project) {
		if (project == null)return;
		
		signal(project, IProjectChangeListener.ProjectDeleted);

		try {
			boolean isMigrated = ConfigurationManager.getManager().isMigrated(project);
			// If it's not migrated, then it hasn't been loaded, and we don't want to load the
			// validator and its prerequisite plug-ins until they're needed.
			if (isMigrated) {
				ValidatorMetaData[] vmds = ConfigurationManager.getManager().getProjectConfiguration(project).getValidators();
				for (ValidatorMetaData vmd : vmds) {

					if (!vmd.isActive()) {
						// If this validator has not been activated, or if it has been shut down,
						// don't activate it again.
						continue;
					}

					IWorkbenchContext helper = null;
					try {
						helper = vmd.getHelper(project);
						helper.deleting();
					} catch (InstantiationException e) {
						// Remove the vmd from the reader's list
						ValidationRegistryReader.getReader().disableValidator(vmd);
						ValidationPlugin.getPlugin().handleException(e);
						continue;
					} catch (Exception e) {
						// If there is a problem with this particular helper, log the error and
						// continue with the next validator.
						ValidationPlugin.getPlugin().handleException(e);
						continue;
					}
				}

//				ConfigurationManager.getManager().deleting(project);
			}
		} catch (InvocationTargetException e) {
			ValidationPlugin.getPlugin().handleException(e);
			if (e.getTargetException() != null)
				ValidationPlugin.getPlugin().handleException(e.getTargetException());

		}
	}

	/**
	 * If a project's description changes, The project may have changed its nature. Update the cache
	 * to reflect the new natures. The project could be opening. Migrate.
	 */
	private void postAutoChange(IResourceDelta delta) {
		if (_postAutoBuildVisitor == null) {
			_postAutoBuildVisitor = new IResourceDeltaVisitor() {
				public boolean visit(IResourceDelta subdelta) throws CoreException {
					if (subdelta == null)return false;

					IResource resource = subdelta.getResource();
					if (resource instanceof IWorkspaceRoot)return true;
					if (resource instanceof IProject) {
						IProject project = (IProject) resource;
						if ((subdelta.getFlags() & IResourceDelta.DESCRIPTION) == IResourceDelta.DESCRIPTION) {
							signal(project, IProjectChangeListener.ProjectChanged);
							return false;
						}

						if ((subdelta.getFlags() & IResourceDelta.OPEN) == IResourceDelta.OPEN) {
							if (project.isOpen()) {
								// Project was just opened. If project.isOpen() had returned false,
								// project would just have been closed.
								opening(project);
							}
							return false;
						}
						
						if ((subdelta.getFlags() & IResourceDelta.ADDED) == IResourceDelta.ADDED) {
							signal(project, IProjectChangeListener.ProjectAdded);
							return false;
						}
					}

					return false;
				}
			};
		}

		try {
			delta.accept(_postAutoBuildVisitor, true);
		} catch (CoreException exc) {
			ValidationPlugin.getPlugin().handleException(exc);
		}
	}

	/**
	 * Notifies this manager that some resource changes have happened on the platform. If the change
	 * is a project deletion, that project should be removed from the cache.
	 * 
	 * @see IResourceDelta
	 * @see IResource
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		if (_shutdown && !isActive()) {
			// If we're shutting down, and nothing has been activated, don't need to do anything.
			return;
		}

		if (Tracing.isLogging()){
			Tracing.log("Eventmanager-01: IResourceChangeEvent type=" + //$NON-NLS-1$
				Misc.resourceChangeEventType(event.getType()) + 
				", resource=" +  //$NON-NLS-1$
				event.getResource() + ", source=" + event.getSource() + ", delta=" +   //$NON-NLS-1$//$NON-NLS-2$
				event.getDelta());				
		}
		
		if (event.getSource() instanceof IWorkspace) {
			boolean isProject = event.getResource() instanceof IProject;
			if ((event.getType() == IResourceChangeEvent.PRE_DELETE) && isProject) {
				deleting((IProject) event.getResource());
			} else if ((event.getType() == IResourceChangeEvent.PRE_CLOSE) && isProject) {
				closing((IProject) event.getResource());
			} else if (event.getType() == IResourceChangeEvent.POST_BUILD) {
				postAutoChange(event.getDelta());
			}
		}
	}

	/**
	 * Notifies this manager that the ValidationPlugin is shutting down. (Usually implies that
	 * either the plug-in could not load, or that the workbench is shutting down.)
	 * <p>
	 * The manager will then notify all active helpers of the shutdown, so that they may perform any
	 * last-minute writes to disk, cleanup, etc.
	 */
	public void shutdown() {
		try {
			// resourceChanged(IResourceChangeEvent) needs to know when a shutdown has started.
			_shutdown = true;

			// If the validators are loaded, then for every project in the workbench,
			// we must see if it has been loaded. If it has, every enabled IWorkbenchContext
			// must be called to clean up. If the project hasn't been loaded, then no
			// IWorkbenchContext built anything, and there's nothing to clean up.
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IWorkspaceRoot workspaceRoot = workspace.getRoot();
			IProject[] projects = workspaceRoot.getProjects();
			ProjectConfiguration prjp = null;
			for (IProject project : projects) {
				if (!project.isOpen()) {
					// If the project isn't opened, there's nothing to clean up.
					// If the project was opened, it would have been migrated, and there's something
					// to clean up.
					continue;
				}

				try {
					boolean isMigrated = ConfigurationManager.getManager().isMigrated(project);
					// If it's not migrated, then it hasn't been loaded, and we don't want to load
					// the validator and its prerequisite plug-ins until they're needed.
					if (isMigrated) {
						prjp = ConfigurationManager.getManager().getProjectConfiguration(project);

						ValidatorMetaData[] vmdList = prjp.getEnabledValidators();
						// if vmdList is null, IProject has never been loaded, so nothing to clean up
						if (vmdList != null) {
							for (int j = 0; j < vmdList.length; j++) {
								ValidatorMetaData vmd = vmdList[j];

								if (!vmd.isActive()) {
									// If this validator has not been activated, or if it has been
									// shut down, don't activate it again.
									continue;
								}

								IWorkbenchContext helper = vmd.getHelper(project);
								if (helper != null) {
									try {
										helper.shutdown();
									} catch (Exception exc) {
										// Since we're shutting down, ignore the exception.
									}
								}
							}
						}
					}
				} catch (InvocationTargetException e) {
					ValidationPlugin.getPlugin().handleException(e);
					if (e.getTargetException() != null)
						ValidationPlugin.getPlugin().handleException(e.getTargetException());

				}
			}
		} catch (Exception exc) {
			// Since we're shutting down, ignore the exception.
		}
	}

	public boolean isActive() {
		// Have to use this convoluted technique for the shutdown problem.
		// i.e., when eclipse is shut down, if validation plug-in hasn't been loaded,
		// the EventManager is activated for the first time, and it
		// sends many exceptions to the .log. At first, I wrote a
		// static method on ValidationRegistryReader, which returned true
		// if the registry had been read, and false otherwise. However,
		// that didn't solve the exception problem, because eclipse's
		// class loader failed to load the ValidationRegistryReader class.
		//
		// The fix is to keep all shutdown mechanisms in this class.
		// Track everything in here.
		return _isActive;
	}

	/**
	 * This method should only be called by the ValidationRegistryReader once the registry has been
	 * read.
	 */
	public void setActive(boolean b) {
		_isActive = b;
	}

	/**
	 * This method should be used to determine if the workbench is running in UI or Headless.
	 * 
	 * @deprecated This plug-in no longer depends on jem. If you need this function use the jem
	 * code directly.
	 */
	public static boolean isHeadless() {
		//return UIContextDetermination.getCurrentContext() == UIContextDetermination.HEADLESS_CONTEXT;
		return false;
	}
}
