/**********************************************************************
 * 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 {
	private Map<IProject, IModule[]> modules = new HashMap<IProject, IModule[]>();

	/**
	 * 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 = 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<IModule> list = new ArrayList<IModule>();
		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 = new HashMap<IProject, IModule[]>();
	}

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