/**********************************************************************
 * Copyright (c) 2002 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/
package org.eclipse.core.internal.resources;

import java.util.*;

import org.eclipse.core.internal.events.ILifecycleListener;
import org.eclipse.core.internal.events.LifecycleEvent;
import org.eclipse.core.internal.utils.Policy;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;

/**
 * An alias is a resource that occupies the same file system location as another
 * resource in the workspace.  When a resource is modified in a way that affects
 * the file on disk, all aliases need to be updated.  This class is used to
 * maintain data structures for quickly computing the set of aliases for a given
 * resource, and for efficiently updating all aliases when a resource changes on
 * disk.
 * 
 * The approach for computing aliases is optimized for alias-free workspaces and
 * alias-free projects.  That is, if the workspace contains no aliases, then
 * updating should be very quick.  If a resource is changed in a project that
 * contains no aliases, it should also be very fast.
 * 
 * The data structures maintained by the alias manager can be seen as a cache,
 * that is, they store no information that cannot be recomputed from other
 * available information.  On shutdown, the alias manager discards all state; on
 * startup, the alias manager eagerly rebuilds its state.  The reasoning is
 * that it's better to incur this cost on startup than on the first attempt to
 * modify a resource.  After startup, the state is updated incrementally on the
 * following occasions: 
 *  -  when projects are deleted, opened, closed, or moved 
 *  - when linked resources are created, deleted, or moved.
 */
public class AliasManager implements IManager, ILifecycleListener {
	/**
	 * Maintains a mapping of IPath->IResource, such that multiple resources
	 * mapped from the same path are tolerated.
	 */
	class LocationMap {
		/**
		 * Map of IPath->IResource OR IPath->ArrayList of (IResource)
		 */
		private final SortedMap map = new TreeMap(getComparator());
		/**
		 * Adds the given resource to the map, keyed by the given location.
		 * Returns true if a new entry was added, and false otherwise.
		 */
		public boolean add(IPath location, IResource resource) {
			Object oldValue = map.get(location);
			if (oldValue == null) {
				map.put(location, resource);
				return true;
			}
			if (oldValue instanceof IResource) {
				if (resource.equals(oldValue))
					return false;//duplicate
				ArrayList newValue = new ArrayList(2);
				newValue.add(oldValue);
				newValue.add(resource);
				map.put(location, newValue);
				return true;
			}
			ArrayList list = (ArrayList)oldValue;
			if (list.contains(resource))
				return false;//duplicate
			list.add(resource);
			return true;
		}
		/**
		 * Method clear.
		 */
		public void clear() {
			map.clear();
		}
		/**
		 * Calls the given doit with every resource in the map whose location
		 * overlaps another resource in the map.
		 */
		public void overLappingResourcesDo(Doit doit) {
			Iterator entries = map.entrySet().iterator();
			IPath previousPath = null;
			IResource previousResource = null;
			while (entries.hasNext()) {
				Map.Entry current = (Map.Entry)entries.next();
				//value is either single resource or List of resources
				IPath currentPath = (IPath)current.getKey();
				IResource currentResource = null;
				Object value = current.getValue();
				if (value instanceof List) {
					//if there are several then they're all overlapping
					Iterator duplicates = ((List)value).iterator();
					while (duplicates.hasNext())
						doit.doit((IResource)duplicates.next());
				} else {
					//value is a single resource
					currentResource = (IResource)value;
				}
				if (previousPath != null) {
					//check for overlap with previous
					//Note: previous is always shorter due to map sorting rules
					if (previousPath.isPrefixOf(currentPath)) {
						//resources will be null if they were in a list, in which case 
						//they've already been passed to the doit
						if (previousResource != null)
							doit.doit(previousResource);
						if (currentResource != null)
							doit.doit(currentResource);
					}
				}
				previousPath = currentPath;
				previousResource = currentResource;
			}
		}
		/**
		 * Removes the given location from the map.  Returns true if anything
		 * was actually removed, and false otherwise.
		 */
		public boolean remove(IPath location, IResource resource) {
			Object oldValue = map.get(location);
			if (oldValue == null)
				return false;
			if (oldValue instanceof IResource) {
				if (resource.equals(oldValue)) {
					map.remove(location);
					return true;
				}
				return false;
			}
			ArrayList list = (ArrayList)oldValue;
			boolean wasRemoved = list.remove(resource);
			if (list.size() == 0)
				map.remove(location);
			return wasRemoved;
		}
	}
	interface Doit {
		public void doit(IResource resource);
	}
	
	/**
	 * This maps IPath->IResource, where the path is an absolute file system
	 * location, and the resource contains the projects and/or linked resources
	 * that are rooted at that location.
	 */
	private final LocationMap locationsMap = new LocationMap();
	
	/**
	 * The set of IProjects that have aliases.
	 */
	private final Set aliasedProjects = new HashSet();
	
	/**
	 * The total number of linked resources that exist in the workspace.  This
	 * count includes linked resources that don't currently have valid locations
	 * (due to an undefined path variable).
	 */
	private int linkedResourceCount = 0;
	
	/** the workspace */
	private final Workspace workspace;

	public AliasManager(Workspace workspace) {
		this.workspace = workspace;
	}
	private void addToLocationsMap(IProject project) {
		IPath location = project.getLocation();
		if (location != null)
			locationsMap.add(location, project);
		try {
			IResource[] members = project.members();
			if (members != null)
				//look for linked resources
				for (int i = 0; i < members.length; i++)
					if (members[i].isLinked())
						addToLocationsMap(members[i]);
		} catch (CoreException e) {
			//skip inaccessible projects
		}
	}
	private void addToLocationsMap(IResource linkedResource) {
		IPath location = linkedResource.getLocation();
		if (location != null)
			if (locationsMap.add(location, linkedResource))
				linkedResourceCount++;
	}

	/**
	 * Builds the table of aliased projects from scratch.
	 */
	private void buildAliasedProjectsSet() {
		aliasedProjects.clear();
		//if there are no linked resources then there can't be any aliased projects
		if (linkedResourceCount <= 0) {
			//paranoid check -- count should never be below zero
//			Assert.isTrue(linkedResourceCount == 0, "Linked resource count below zero");//$NON-NLS-1$
			return;
		}
		//for every resource that overlaps another, marked its project as aliased
		locationsMap.overLappingResourcesDo(new Doit() {
			public void doit(IResource resource) {
				aliasedProjects.add(resource.getProject());
			}
		});
	}
		/**
		 * Builds the table of resource locations from scratch.  Also computes an
		 * initial value for the linked resource counter.
		 */
	private void buildLocationsMap() {
		locationsMap.clear();
		linkedResourceCount = 0;
		//build table of IPath (file system location) -> IResource (project or linked resource)
		IProject[] projects = workspace.getRoot().getProjects();
		for (int i = 0; i < projects.length; i++) {
			addToLocationsMap(projects[i]);
		}
	}
	public void removeFromLocationsMap(IProject project) {
		//remove this project and all linked children from the location table
		IPath location = project.getLocation();
		if (location != null)
			locationsMap.remove(location, project);
		IResource[] children = null;
		try {
			children = project.members();
		} catch (CoreException e) {
			//ignore inaccessible projects
		}
		if (children != null) {
			for (int i = 0; i < children.length; i++) {
				if (children[i].isLinked()) {
					removeFromLocationsMap(children[i]);
				}
			}
		}
	}
	public void removeFromLocationsMap(IResource linkedResource) {
		//this linked resource is being deleted
		IPath location = linkedResource.getLocation();
		if (location != null)
			if (locationsMap.remove(location, linkedResource));
				linkedResourceCount--;
	}
	/**
	 * Returns the comparator to use when sorting the locations map.  Comparison
	 * is based on segments, so that paths with the most segments in common will
	 * always be adjacent.  This is equivalent to the natural order on the path
	 * strings, with the extra condition that the path separator is ordered
	 * before all other characters. (Ex: "/foo" < "/foo/zzz" < "/fooaaa").
	 */
	private Comparator getComparator() {
		return new Comparator() {
			public int compare(Object o1, Object o2) {
				IPath path1 = (IPath) o1;
				IPath path2 = (IPath) o2;
				int segmentCount1 = path1.segmentCount();
				int segmentCount2 = path2.segmentCount();
				for (int i = 0; (i < segmentCount1) && (i < segmentCount2); i++) {
					String segment1 = path1.segment(i);
					String segment2 = path2.segment(i);
					int compare = segment1.compareTo(segment2);
					if (compare != 0)
						return compare;
				}
				//all segments are equal, so they are the same if they have the same number of segments
				return segmentCount1-segmentCount2;
			}
		};
	}
	public void handleEvent(LifecycleEvent event) throws CoreException {
		switch (event.kind) {
			case LifecycleEvent.PRE_PROJECT_CLOSE:
			case LifecycleEvent.PRE_PROJECT_DELETE:
				removeFromLocationsMap((IProject)event.resource);
				break;
			case LifecycleEvent.PRE_PROJECT_MOVE:
			case LifecycleEvent.PRE_PROJECT_OPEN:
				addToLocationsMap((IProject)event.resource);
				buildAliasedProjectsSet();
				break;
			case LifecycleEvent.PRE_LINK_DELETE:
			case LifecycleEvent.PRE_LINK_MOVE:
			case LifecycleEvent.POST_LINK_CREATE:
		}
		//rebuild the set of aliased projects from scratch
		buildAliasedProjectsSet();
	}
	/**
	 * Method moving.
	 * @param source
	 * @param destination
	 * @param updateFlags
	 */
	public void moving(IResource source, IResource destination, int updateFlags) {
		// todo
	}

	/**
	 * @see IManager#shutdown
	 */
	public void shutdown(IProgressMonitor monitor) throws CoreException {
	}
	
	/**
	 * @see IManager#startup
	 */
	public void startup(IProgressMonitor monitor) throws CoreException {
		workspace.addLifecycleListener(this);
		buildLocationsMap();
		buildAliasedProjectsSet();
	}

	/**
	 * The file underlying the given resource has changed on disk.  Compute all
	 * aliases for this resource and update them.  This method will not attempt
	 * to incur any units of work on the given progress monitor, but it may
	 * update the subtask to reflect what aliases are being updated.
	 */
	public void updateAliases(IResource resource, IProgressMonitor monitor) throws CoreException {
		//nothing to do if we're in an alias-free workspace or project
		if (linkedResourceCount <= 0 || !aliasedProjects.contains(resource.getProject()))
			return;
		IResource[] aliases = computeAliases(resource);
		if (aliases == null)
			return;
		for (int i = 0; i < aliases.length; i++) {
			monitor.subTask(Policy.bind("links.updatingDuplicate", resource.getFullPath().toString()));//$NON-NLS-1$
			aliases[i].refreshLocal(IResource.DEPTH_INFINITE, null);
		}
	}
	/**
	 * Returns all aliases of the given resource, or null if there are none.
	 * This list will NOT include the resource itself.
	 */
	private IResource[] computeAliases(IResource resource) {
		// todo
		return null;
	}
	/**
	 * Notification of creation of a linked reousr.cds
	 */
	public void creating(IResource linkedResource) {
		addToLocationsMap(linkedResource);
		buildAliasedProjectsSet();
	}
}