/**********************************************************************
 * Copyright (c) 2003, 2007 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.server.core.util;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.internal.ModuleFactory;
import org.eclipse.wst.server.core.internal.ServerPlugin;
import org.eclipse.wst.server.core.internal.Trace;
import org.eclipse.wst.server.core.model.ModuleFactoryDelegate;
/**
 * A helper class for defining a module factory that provides modules
 * based on projects.
 * 
 * @since 1.0
 */
public abstract class ProjectModuleFactoryDelegate extends ModuleFactoryDelegate {
	// map of IProject to IModule[]
	private Map modules = new HashMap();

	/**
	 * Construct a new ProjectModuleFactoryDelegate.
	 */
	public ProjectModuleFactoryDelegate() {
		super();
	}

	/**
	 * Cache modules that exist in the given project.
	 * 
	 * @param project a project to cache
	 * @since 2.0
	 */
	private final IModule[] cacheModules(IProject project) {
		if (project == null || !project.isAccessible())
			return null;
		
		IModule[] m = null;
		try {
			m = (IModule[]) modules.get(project);
			if (m != null)
				return m;
		} catch (Exception e) {
			// ignore
		}
		
		try {
			m = createModules(project);
			if (m != null) {
				modules.put(project, m);
				return m;
			}
		} catch (Throwable t) {
			Trace.trace(Trace.SEVERE, "Error creating module", t);
		}
		return new IModule[0];
	}

	/**
	 * Cache all existing modules.
	 */
	private final void cacheModules() {
		try {
			IProject[] projects = getWorkspaceRoot().getProjects();
			int size = projects.length;
			for (int i = 0; i < size; i++) {
				if (projects[i].isAccessible()) {
					boolean cache = true;
					try {
						Object o = modules.get(projects[i]);
						if (o != null)
							cache = false;
					} catch (Exception e) {
						// ignore
					}
					
					if (cache) {
						try {
							IModule[] modules2 = createModules(projects[i]);
							if (modules2 != null)
								modules.put(projects[i], modules2);
						} catch (Throwable t) {
							Trace.trace(Trace.SEVERE, "Error creating module for " + projects[i].getName(), t);
						}
					}
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error caching modules", e);
		}
	}

	/**
	 * Returns the workspace root.
	 * 
	 * @return the workspace root
	 */
	private static IWorkspaceRoot getWorkspaceRoot() {
		return ResourcesPlugin.getWorkspace().getRoot();
	}

	/*
	 * @see ModuleFactoryDelegate#getModules()
	 */
	public final IModule[] getModules() {
		cacheModules();
		
		List list = new ArrayList();
		Iterator iter = modules.values().iterator();
		while (iter.hasNext()) {
			IModule[] m = (IModule[]) iter.next();
			if (m != null)
				list.addAll(Arrays.asList(m));
		}
		
		IModule[] modules2 = new IModule[list.size()];
		list.toArray(modules2);
		return modules2;
	}

	/**
	 * Handle changes to a project.
	 * 
	 * @param project a project
	 * @param delta a resource delta
	 */
	public final static void handleGlobalProjectChange(IProject project, IResourceDelta delta) {
		ModuleFactory[] factories = ServerPlugin.getModuleFactories();
		int size = factories.length;
		for (int i = 0; i < size; i++) {
			if (factories[i].delegate != null && factories[i].delegate instanceof ProjectModuleFactoryDelegate) {
				ProjectModuleFactoryDelegate pmfd = (ProjectModuleFactoryDelegate) factories[i].delegate;
				if (pmfd.deltaAffectsModules(delta)) {
					pmfd.clearCache(project);
					pmfd.clearCache();
				}
			}
		}
	}

	/**
	 * Returns <code>true</code> if the delta may have changed modules,
	 * and <code>false</code> otherwise.
	 * 
	 * @param delta a resource delta
	 * @return <code>true</code> if the delta may have changed modules,
	 *    and <code>false</code> otherwise
	 */
	private final boolean deltaAffectsModules(IResourceDelta delta) {
		final boolean[] b = new boolean[1];
		
		final IPath[] listenerPaths = getListenerPaths();
		if (listenerPaths == null || listenerPaths.length == 0)
			return false;
		final int size = listenerPaths.length;
		
		try {
			delta.accept(new IResourceDeltaVisitor() {
				public boolean visit(IResourceDelta delta2) throws CoreException {
					if (b[0])
						return false;
					//Trace.trace(Trace.FINEST, delta2.getResource() + "  " + delta2.getKind() + " " + delta2.getFlags());
					boolean ok = false;
					IPath path = delta2.getProjectRelativePath();
					for (int i = 0; i < size; i++) {
						if (listenerPaths[i].equals(path)) {
							b[0] = true;
							return false;
						} else if (path.isPrefixOf(listenerPaths[i])) {
							ok = true;
						}
					}
					return ok;
				}
			});
		} catch (Exception e) {
			// ignore
		}
		//Trace.trace(Trace.FINEST, "Delta contains change: " + t.b);
		return b[0];
	}

	/**
	 * Clear cached metadata.
	 * 
	 * @deprecated use {@link #clearCache(IProject)} instead
	 */
	protected void clearCache() {
		// ignore
	}

	/**
	 * Clear cached metadata.
	 * 
	 * @since 2.0
	 */
	protected void clearCache(IProject project) {
		//modules.put(project, null);
		modules = new HashMap();
	}

	/**
	 * Creates the module for a given project.
	 * 
	 * @param project a project to create modules for
	 * @return a module, or <code>null</code> if there was no module in the project
	 * @see #createModules(IProject)
	 * @deprecated Use createModules(IProject) instead, which supports multiple modules
	 *    per project
	 */
	protected IModule createModule(IProject project) {
		return null;
	}

	/**
	 * Creates the modules that are contained within a given project.
	 * 
	 * @param project a project to create modules for
	 * @return a possibly-empty array of modules
	 */
	protected IModule[] createModules(IProject project) {
		IModule module = createModule(project);
		if (module == null)
			return new IModule[0];
		
		return new IModule[] { module };
	}

	/**
	 * Returns the list of resources that the module should listen to
	 * for state changes. The paths should be project relative paths.
	 * Subclasses can override this method to provide the paths.
	 *
	 * @return a possibly empty array of paths
	 */
	protected IPath[] getListenerPaths() {
		return null;
	}

	/*
	 * @see ModuleFactoryDelegate#getModules(IProject)
	 * @since 2.0
	 */
	public IModule[] getModules(IProject project) {
		return cacheModules(project);
	}

	/*
	 * @see ModuleFactoryDelegate#findModule(String)
	 * @since 2.0
	 */
	public IModule findModule(String id) {
		try {
			// first assume that the id is a project name
			IProject project = getWorkspaceRoot().getProject(id);
			if (project != null) {
				IModule[] m = cacheModules(project);
				if (m != null) {
					int size = m.length;
					for (int i = 0; i < size; i++) {
						String id2 = m[i].getId();
						int index = id2.indexOf(":");
						if (index >= 0)
							id2 = id2.substring(index+1);
						
						if (id.equals(id2))
							return m[i];
					}
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.FINER, "Could not find " + id + ". Reverting to default behaviour");
		}
		
		// otherwise default to searching all modules
		return super.findModule(id);
	}
}