/***************************************************************************************************
 * Copyright (c) 2005, 2006 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.jst.jsf.facesconfig.util;

import java.util.LinkedList;
import java.util.ListIterator;

import org.eclipse.core.resources.IFile;
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.IResourceVisitor;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jst.jsf.facesconfig.FacesConfigPlugin;
import org.eclipse.jst.jsf.facesconfig.internal.Logger;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;

/**
 * This class is responsible for the following:
 * <ol>
 * <li>Ensure that the Struts nature is added to any project to which a Struts
 * config. file is added.</li>
 * <li>Ensure that the Struts nature is added to any project to which a diagram
 * file is added.</li>
 * <li>Restart project(s) if/as apporopriate when a Struts config. file is
 * modified.
 * </ol>
 * It arguably should be multiple classes, but the things it does are closely
 * related and splitting it up would result in duplicate work as well as
 * multiple delta traversals.
 */
public class FacesResourceChangeListener implements IResourceChangeListener,
		IResourceDeltaVisitor, ISaveParticipant, IResourceVisitor {

	/** The singleton instance. */
	private static FacesResourceChangeListener listener;
	private static boolean restartInProgress = false;
	private LinkedList facesConfigChangeListeners = new LinkedList();
	
	private static IPreferenceStore preferenceStore = null;

	private static final QualifiedName EDITOR_KEY = new QualifiedName(
			"org.eclipse.ui.internal.registry.ResourceEditorRegistry", "EditorProperty");//$NON-NLS-2$//$NON-NLS-1$

	/** Start up the singleton instance. */
	public static void startup() {

		// Bail if we're already started.
		if (listener != null)
			return;

		// Create the singleton instance.
		listener = new FacesResourceChangeListener();

		// Register as resource change listener.
		ResourcesPlugin.getWorkspace().addResourceChangeListener(
				listener,
				IResourceChangeEvent.PRE_BUILD + IResourceChangeEvent.POST_BUILD);
	}

	/** Shutdown the singleton instance. */
	public static void shutdown() {

		// Bail if we're not started.
		if (listener == null)
			return;

		// Deregister as save participant.
		ResourcesPlugin.getWorkspace().removeSaveParticipant(FacesConfigPlugin.getPlugin());

		// Deregister as resource change listener.
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(listener);

		// Dereference the singleton instance.
		listener = null;
	}

	/**
	 * Only this class can create instances.
	 */
	private FacesResourceChangeListener() {
        // no local instantiation
	}

	/**
	 * Process a resource change event. This should be invoked only from the
	 * workbench.
	 * 
	 * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {

		IResourceDelta delta = event.getDelta();
		if (delta != null) {
			FacesConfigChangeEvent facesConfigChangeEvent = new FacesConfigChangeEvent();
			fireFacesConfigChangeEvent(facesConfigChangeEvent);

			try {
				delta.accept(this);
			} catch (CoreException ignored) {
				Logger.log(this, ignored);
			}
		}

		// Restart projects, if necessary.
		if ((delta != null) && (event.getType() == IResourceChangeEvent.POST_BUILD)) {
			FacesConfigRestartServerResourceDeltaVisitor visitor = new FacesConfigRestartServerResourceDeltaVisitor();
			try {
				delta.accept(visitor);
			} catch (CoreException ignored) {
				Logger.log(this, ignored);
			}
			//restartComponents(visitor.getComponents());
		}
	}

	/**
	 * Visit a resource delta. This should be invoked only from the
	 * IResourceDelta.accept() method invoked above.
	 * 
	 * @see IResourceDeltaVisitor#visit(IResourceDelta)
	 */
	public boolean visit(IResourceDelta delta) throws CoreException {

		// Check for and handle it if it's a Struts config. file.
		checkForFacesConfigFile(delta);

		// Done.
		return true;
	}

	private void checkForFacesConfigFile(IResourceDelta delta) {
		boolean isAdded = delta.getKind() == IResourceDelta.ADDED;
		if (isAdded
				|| ((delta.getKind() == IResourceDelta.CHANGED) && ((delta.getFlags() & (IResourceDelta.CONTENT
						| IResourceDelta.TYPE | IResourceDelta.SYNC | IResourceDelta.REPLACED)) != 0))) {
			checkForFacesConfigFile(delta.getResource(), !isAdded);
		}
	}

	private void checkForFacesConfigFile(IResource resource, boolean ignoreNonFacesProjects) {
		if (resource.getType() == IResource.FILE) {

			// See if the file is a Struts config. file.
			// If the file was just added, we check the file regardless of
			// whether or not it is in a Struts project.
			// Otherwise, a file in a non-Struts project is considered to not be
			// a Struts config. file.
			IFile file = (IFile) resource;
			if (FacesConfigUtil.isFacesConfigFile(file, ignoreNonFacesProjects)) {

				// Ensure that the project has the Struts nature.
				// TODO:
				// StrutsNatureRuntime.ensureProjectHasStrutsNature(file.getProject());
				IVirtualComponent component = ComponentUtilities.findComponent(file);
				if (component != null) {
					restartServerIfNecessary(component);
					// Try to register the SCFE as the default editor.
					setRegistration(file);
				}
			} else {
				// Try to unregister the SCFE as the default editor.
				unsetRegistration(file);
			}
		}
	}

	/**
	 * Look to see if the persisted resource level property keyed by EDITOR_KEY
	 * has ben set yet. If not then set it to the SCFE.
	 * 
	 * @param file
	 *            The FCF
	 */
	private void setRegistration(IFile file) {
		String editorID = null;
		try {
			editorID = file.getPersistentProperty(EDITOR_KEY);
		} catch (CoreException e) {
            // suppress core exception
		}
		if (editorID == null) {
			try {
				file.setPersistentProperty(EDITOR_KEY, FacesConfigPlugin.FACES_CONFIG_EDITOR_ID);
			} catch (CoreException e) {
				Logger.log(file, "Failed to set the vcurrent editor to SCFE", e);
			}
		}
	}

	private void unsetRegistration(IFile file) {
		// If the default editor for this file is not the Struts config. editor,
		// then we're done.
		IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
		IEditorDescriptor userEditor = registry.getDefaultEditor(file.getFullPath().toString());
		if ((userEditor == null)
				|| !FacesConfigPlugin.FACES_CONFIG_EDITOR_ID.equals(userEditor.getId())) {
			traceFiner(file, "Not unsetting: Default already not Faces config. editor");
			return;
		}

		// Make the Struts config. editor the default.
		traceFiner(file, "Unsetting.");
		IEditorDescriptor[] editors = registry.getEditors(file.getFullPath().toString());
		if (editors.length > 1) {
			registry.setDefaultEditor(file.getFullPath().toString(), editors[1].getId());
		}
	}

	//private boolean isRestarting = false;
	//private Collection restartableComponents = new HashSet();

/*	private void restartComponents(Collection components) {
		restartableComponents.addAll(components);
		if (!isRestarting) {
			isRestarting = true;
			try {
				while (!restartableComponents.isEmpty()) {
					IVirtualComponent component = (IVirtualComponent) restartableComponents.iterator().next();
					try {
						ServerRestartUtil.restartComponent(component, true);
					} finally {
						restartableComponents.remove(component);
					}
				}
			} finally {
				isRestarting = false;
			}

		}
	}

*/	private void traceFiner(IFile file, String message) {
		String fileName = file.getProjectRelativePath().toString();
		Logger.trace("FacesconfigPlugin", this, fileName + ": " + message);
	}

	/** @see ISaveParticipant#doneSaving(ISaveContext) */
	public void doneSaving(ISaveContext context) {
        // nothing to do
	}

	/** @see ISaveParticipant#prepareToSave(ISaveContext) */
	public void prepareToSave(ISaveContext context) throws CoreException {
        // nothing to do
	}

	/** @see ISaveParticipant#rollback(ISaveContext) */
	public void rollback(ISaveContext context) {
	    // nothing to do
	}

	/** @see ISaveParticipant#saving(ISaveContext) */
	public void saving(ISaveContext context) throws CoreException {
		context.needDelta();
	}

	/**
	 * Visit a resource. This should be invoked only from the
	 * IResource.accept(IResourceVisitor) invocation, above.
	 * 
	 * @see IResourceVisitor#visit(IResource)
	 */
	public boolean visit(IResource resource) {

		// Check for and handle a Struts config. file.
		checkForFacesConfigFile(resource, true);

		// Continue.
		return true;
	}

	private void restartServerIfNecessary(IVirtualComponent component) {
		if(!restartInProgress) {
			// check against preference about whether to automatically restart
			boolean restart = false;
			if (FacesResourceChangeListener.preferenceStore != null) {
				restart = FacesResourceChangeListener.preferenceStore.getBoolean(IFacesconfigPreferences.PREFSKEY_SERVER_RESTART);
			}
			if(restart) {
				restartInProgress = true;
				// we'll ask that just the containing EAR is restarted, but it may cycle the whole server if running on Portal

				//ServerRestartUtil.restartComponent(component, true);
				restartInProgress = false;
			}
		}
	}

	/**
	 * @return Returns the listener.
	 */
	public static FacesResourceChangeListener getFacesResourceChangeListener() {
		if (listener == null) {
			listener = new FacesResourceChangeListener();
			// Register as resource change listener.
			ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_BUILD);
		}
		return listener;
	}
	
	/**
	 * Adds a change listener to the list of listeners that will be notified
	 * when a change is fired.
	 * 
	 * @param facesConfigChangeListener
	 */
	public void addFacesConfigChangeListener(IFacesConfigChangeListener facesConfigChangeListener) {
		facesConfigChangeListeners.add(facesConfigChangeListener);
	}
	/**
	 * Removes the listener from the list.
	 * 
	 * @param facesConfigChangeListener
	 */
	public void removeFacesConfigChangeListener(IFacesConfigChangeListener facesConfigChangeListener) {
		facesConfigChangeListeners.remove(facesConfigChangeListener);
	}
	
	private void fireFacesConfigChangeEvent(IFacesConfigChangeEvent event) {
		LinkedList localCopy;
		synchronized( this ) {
			localCopy = (LinkedList)facesConfigChangeListeners.clone();
		}
		for ( ListIterator iter = localCopy.listIterator(); iter.hasNext(); ) {
			IFacesConfigChangeListener facesConfigChangeListener = (IFacesConfigChangeListener)iter.next();
			facesConfigChangeListener.resourceChanged(event);
		}
	}

	/** 
	 * Set the internally used preference store to preferenceStore
	 * 
	 * @param preferenceStore
	 */
	public static void setPreferenceStore(IPreferenceStore preferenceStore) {
		FacesResourceChangeListener.preferenceStore = preferenceStore;
	}
}