/*******************************************************************************
 * Copyright (c) 2000, 2015 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.ui.internal.ide;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

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.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetUpdater;

/**
 * A working set updater that updates resource working sets on resource deltas
 *
 * @since 3.2
 */
public class ResourceWorkingSetUpdater implements IWorkingSetUpdater,
		IResourceChangeListener {

	/**
	 * Utility class used to help process incoming resource deltas.
	 */
	private static class WorkingSetDelta {
		private IWorkingSet fWorkingSet;

		private List fElements;

		private boolean fChanged;

		/**
		 * Create a new instance of this class.
		 *
		 * @param workingSet
		 *            the working set to track.
		 */
		public WorkingSetDelta(IWorkingSet workingSet) {
			fWorkingSet = workingSet;
			fElements = new ArrayList(Arrays.asList(workingSet.getElements()));
		}

		/**
		 * Returns the index of this element in the list of known elements.
		 *
		 * @param element
		 *            the element to search for
		 * @return the index, or -1 if unknown.
		 */
		public int indexOf(Object element) {
			return fElements.indexOf(element);
		}

		/**
		 * Add a new element to the list of known elements.
		 *
		 * @param index
		 *            the index at which to place the element
		 * @param element
		 *            the element to set
		 */
		public void set(int index, Object element) {
			fElements.set(index, element);
			fChanged = true;
		}

		/**
		 * Remove an element from the list of known elements.
		 *
		 * @param index
		 *            the index of the element to remove
		 */
		public void remove(int index) {
			if (fElements.remove(index) != null) {
				fChanged = true;
			}
		}

		/**
		 * Process the changes to this delta and update the working set if
		 * necessary.
		 */
		public void process() {
			if (fChanged) {
				fWorkingSet.setElements((IAdaptable[]) fElements
						.toArray(new IAdaptable[fElements.size()]));
			}
		}
	}

	private List fWorkingSets;

	/**
	 * Create a new instance of this updater.
	 */
	public ResourceWorkingSetUpdater() {
		fWorkingSets = new ArrayList();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this,
				IResourceChangeEvent.POST_CHANGE);
	}

	@Override
	public void add(IWorkingSet workingSet) {
		checkElementExistence(workingSet);
		synchronized (fWorkingSets) {
			fWorkingSets.add(workingSet);
		}
	}

	@Override
	public boolean remove(IWorkingSet workingSet) {
		boolean result;
		synchronized (fWorkingSets) {
			result = fWorkingSets.remove(workingSet);
		}

		return result;
	}

	@Override
	public boolean contains(IWorkingSet workingSet) {
		synchronized (fWorkingSets) {
			return fWorkingSets.contains(workingSet);
		}
	}

	@Override
	public void dispose() {
		synchronized (fWorkingSets) {
			fWorkingSets.clear();
		}
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta();
		if (delta == null) {
			return;
		}
		IWorkingSet[] workingSets;
		synchronized (fWorkingSets) {
			workingSets = (IWorkingSet[]) fWorkingSets
					.toArray(new IWorkingSet[fWorkingSets.size()]);
		}
		for (IWorkingSet workingSet : workingSets) {
			WorkingSetDelta workingSetDelta = new WorkingSetDelta(workingSet);
			processResourceDelta(workingSetDelta, delta);
			workingSetDelta.process();
		}
	}

	private void processResourceDelta(WorkingSetDelta result,
			IResourceDelta delta) {
		IResource resource = delta.getResource();
		int type = resource.getType();
		int index = result.indexOf(resource);
		int kind = delta.getKind();
		int flags = delta.getFlags();
		if (kind == IResourceDelta.CHANGED && type == IResource.PROJECT
				&& index != -1) {
			if ((flags & IResourceDelta.OPEN) != 0) {
				result.set(index, resource);
			}
		}
		if (index != -1 && kind == IResourceDelta.REMOVED) {
			if ((flags & IResourceDelta.MOVED_TO) != 0) {
				result.set(index, ResourcesPlugin.getWorkspace().getRoot()
						.findMember(delta.getMovedToPath()));
			} else {
				result.remove(index);
			}
		}

		// Don't dive into closed or opened projects
		if (projectGotClosedOrOpened(resource, kind, flags)) {
			return;
		}

		for (IResourceDelta child : delta.getAffectedChildren()) {
			processResourceDelta(result, child);
		}
	}

	private boolean projectGotClosedOrOpened(IResource resource, int kind,
			int flags) {
		return resource.getType() == IResource.PROJECT
				&& kind == IResourceDelta.CHANGED
				&& (flags & IResourceDelta.OPEN) != 0;
	}

	private void checkElementExistence(IWorkingSet workingSet) {
		List elements = new ArrayList(Arrays.asList(workingSet.getElements()));
		boolean changed = false;
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			IAdaptable element = (IAdaptable) iter.next();
			boolean remove = false;
			if (element instanceof IProject) {
				IProject project = (IProject) element;
				remove = !project.exists();
			} else if (element instanceof IResource) {
				IResource resource = (IResource) element;
				IProject project = resource.getProject();
				remove = (project != null ? project.isOpen() : true)
						&& !resource.exists();
			}
			if (remove) {
				iter.remove();
				changed = true;
			}
		}
		if (changed) {
			workingSet.setElements((IAdaptable[]) elements
					.toArray(new IAdaptable[elements.size()]));
		}
	}
}
