/*******************************************************************************
 * Copyright (c) 2004, 2008 Tasktop Technologies 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:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.team.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.context.core.IInteractionElement;
import org.eclipse.mylyn.internal.resources.ui.ResourcesUiBridgePlugin;
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.mylyn.team.ui.AbstractActiveChangeSetProvider;
import org.eclipse.mylyn.team.ui.AbstractContextChangeSetManager;
import org.eclipse.mylyn.team.ui.IContextChangeSet;
import org.eclipse.team.internal.core.subscribers.ActiveChangeSet;
import org.eclipse.team.internal.core.subscribers.ActiveChangeSetManager;
import org.eclipse.team.internal.core.subscribers.ChangeSet;
import org.eclipse.team.internal.core.subscribers.IChangeSetChangeListener;

/**
 * NOTE: this class contains several work-arounds for change set limitations in the Platform/Team support.
 * 
 * @author Mik Kersten
 */
public class ContextActiveChangeSetManager extends AbstractContextChangeSetManager {

	private final List<ActiveChangeSetManager> changeSetManagers = new ArrayList<ActiveChangeSetManager>();

	private final List<IContextChangeSet> activeChangeSets = new ArrayList<IContextChangeSet>();

	private static final String LABEL_NO_TASK = "<No Active Task>"; //$NON-NLS-1$

	private static final String HANDLE_NO_TASK = "org.eclipse.mylyn.team.ui.inactive.proxy"; //$NON-NLS-1$

	private final Map<ActiveChangeSetManager, ActiveChangeSet> noTaskSetMap = new HashMap<ActiveChangeSetManager, ActiveChangeSet>();;

	private final Map<ActiveChangeSetManager, ChangeSetChangeListener> listenerByManager = new HashMap<ActiveChangeSetManager, ChangeSetChangeListener>();

	private final ITask noTaskActiveProxy = new LocalTask(HANDLE_NO_TASK, LABEL_NO_TASK);

	/**
	 * Used to restore change sets managed with task context when platform deletes them, bug 168129
	 */
	private class ChangeSetChangeListener implements IChangeSetChangeListener {

		private final ActiveChangeSetManager manager;

		public ChangeSetChangeListener(ActiveChangeSetManager manager) {
			this.manager = manager;
		}

		public void setRemoved(ChangeSet set) {
			if (set instanceof IContextChangeSet) {
				IContextChangeSet contextChangeSet = (IContextChangeSet) set;
				// never matches the noTask change set: its task is never active
				if (contextChangeSet.getTask() != null && contextChangeSet.getTask().isActive()) {
					// put it back
					manager.add((ActiveChangeSet) contextChangeSet);
				}
			}
		}

		public void setAdded(ChangeSet set) {
			// ignore
		}

		public void defaultSetChanged(ChangeSet previousDefault, ChangeSet set) {
			// ignore
		}

		public void nameChanged(ChangeSet set) {
			// ignore
		}

		public void resourcesChanged(ChangeSet set, IPath[] paths) {
			// ignore
		}

	};

	public ContextActiveChangeSetManager() {
		Collection<AbstractActiveChangeSetProvider> providerList = FocusedTeamUiPlugin.getDefault()
				.getActiveChangeSetProviders();
		for (AbstractActiveChangeSetProvider provider : providerList) {
			ActiveChangeSetManager changeSetManager = provider.getActiveChangeSetManager();
			if (changeSetManager != null) {
				changeSetManagers.add(changeSetManager);
			}
		}
	}

	@Override
	protected void updateChangeSetLabel(ITask task) {
		for (ActiveChangeSetManager collector : changeSetManagers) {
			ChangeSet[] sets = collector.getSets();
			for (ChangeSet set : sets) {
				if (set instanceof IContextChangeSet) {
					IContextChangeSet contextChangeSet = (IContextChangeSet) set;
					if (contextChangeSet.getTask().equals(task)) {
						contextChangeSet.updateLabel();
					}
				}
			}
		}
	}

	@Override
	public void enable() {
		super.enable();
		for (ActiveChangeSetManager collector : changeSetManagers) {
			ChangeSetChangeListener listener = listenerByManager.get(collector);
			if (listener == null) {
				listener = new ChangeSetChangeListener(collector);
				listenerByManager.put(collector, listener);
				collector.addListener(listener);
			}
		}
	}

	@Override
	public void disable() {
		super.disable();
		for (ActiveChangeSetManager collector : changeSetManagers) {
			ChangeSetChangeListener listener = listenerByManager.get(collector);
			if (listener != null) {
				collector.removeListener(listener);
				listenerByManager.remove(collector);
			}
		}
	}

	@Override
	protected void initContextChangeSets() {
		// replace existing change sets with IContextChangeSet
		for (ActiveChangeSetManager manager : changeSetManagers) {
			ChangeSet[] sets = manager.getSets();
			for (ChangeSet restoredSet : sets) {
				if (!(restoredSet instanceof IContextChangeSet)) {
					String encodedTitle = restoredSet.getName();
					String taskHandle = ContextChangeSet.getHandleFromPersistedTitle(encodedTitle);
					ITask task = TasksUi.getRepositoryModel().getTask(taskHandle);
					if (task != null) {
						try {
							IContextChangeSet contextChangeSet = getOrCreateSet(manager, task);
							if (contextChangeSet instanceof ActiveChangeSet) {
								contextChangeSet.restoreResources(restoredSet.getResources());
								manager.remove(restoredSet);
								manager.add((ActiveChangeSet) contextChangeSet);
							}
						} catch (Exception e) {
							StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN,
									"Could not restore change set", e)); //$NON-NLS-1$
						}
					}
				}
			}
		}
	}

	/**
	 * For testing.
	 */
	public void clearActiveChangeSets() {
		activeChangeSets.clear();
	}

	public IResource[] getResources(ITask task) {
		for (ActiveChangeSetManager collector : changeSetManagers) {
			ChangeSet[] sets = collector.getSets();
			for (ChangeSet set : sets) {
				if (set instanceof IContextChangeSet) {
					IContextChangeSet contextChangeSet = (IContextChangeSet) set;
					if (contextChangeSet.getTask().equals(task) && contextChangeSet instanceof ActiveChangeSet) {
						return ((ActiveChangeSet) contextChangeSet).getResources();
					}
				}
			}
		}
		return null;
	}

	// TODO m4.0 remove deprecated method that is needed maintain backwards compatibility
	@SuppressWarnings( { "restriction", "deprecation" })
	@Override
	public void contextActivated(IInteractionContext context) {
		try {
			ITask task = getTask(context);
			if (task != null) {
				for (ActiveChangeSetManager manager : changeSetManagers) {
					IContextChangeSet contextChangeSet = getOrCreateSet(manager, task);
					if (contextChangeSet instanceof ActiveChangeSet) {
						ActiveChangeSet activeChangeSet = (ActiveChangeSet) contextChangeSet;
						List<IResource> interestingResources = ResourcesUiBridgePlugin.getDefault()
								.getInterestingResources(context);
						activeChangeSet.add(interestingResources.toArray(new IResource[interestingResources.size()]));
						activeChangeSets.add(contextChangeSet);

						// makeDefault() will add the change set 
//						if (!manager.contains(activeChangeSet)) {
//							manager.add(activeChangeSet);
//						}
						manager.makeDefault(activeChangeSet);
					}
				}
			}
		} catch (Exception e) {
			StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN, "Could not update change set", e)); //$NON-NLS-1$
		}
	}

	private IContextChangeSet getOrCreateSet(ActiveChangeSetManager manager, ITask task) {
		ChangeSet[] sets = manager.getSets();
		for (ChangeSet set : sets) {
			if (set instanceof IContextChangeSet && task.equals(((IContextChangeSet) set).getTask())) {
				return (IContextChangeSet) set;
			}
		}
		// change set does not exist, create a new one
		AbstractActiveChangeSetProvider provider = FocusedTeamUiPlugin.getDefault().getActiveChangeSetProvider(manager);
		return provider.createChangeSet(task);
	}

	// TODO m4.0 remove deprecated method that is needed maintain backwards compatibility
	@SuppressWarnings("deprecation")
	@Override
	public void contextDeactivated(IInteractionContext context) {
		for (ActiveChangeSetManager collector : changeSetManagers) {
			ChangeSet[] sets = collector.getSets();
			for (ChangeSet set : sets) {
				if (set instanceof ActiveChangeSet) {
					IResource[] resources = set.getResources();
					if (resources == null || resources.length == 0) {
						collector.remove(set);
					}
				}
			}
			// First look for it in the collector, then in our cache
			ActiveChangeSet noTaskSet = collector.getSet(LABEL_NO_TASK);
			if (noTaskSet == null) {
				noTaskSet = noTaskSetMap.get(collector);
			}

			if (noTaskSet == null) {
				AbstractActiveChangeSetProvider changeSetProvider = FocusedTeamUiPlugin.getDefault()
						.getActiveChangeSetProvider(collector);
				noTaskSet = (ActiveChangeSet) changeSetProvider.createChangeSet(noTaskActiveProxy);
				collector.add(noTaskSet);
				noTaskSetMap.put(collector, noTaskSet);
			}
			// TODO: not great to do the lookup based on a String value in case the user created this set
			collector.makeDefault(noTaskSet);
			noTaskSet.remove(noTaskSet.getResources());
			collector.remove(noTaskSet);
		}
		activeChangeSets.clear();
	}

	// TODO m4.0 remove deprecated method that is needed maintain backwards compatibility
	@SuppressWarnings( { "restriction", "deprecation" })
	@Override
	public void interestChanged(List<IInteractionElement> elements) {
		for (IInteractionElement element : elements) {
			AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(element.getContentType());
			try {
				if (bridge.isDocument(element.getHandleIdentifier())) {
					IResource resource = ResourcesUiBridgePlugin.getDefault().getResourceForElement(element, false);
					if (resource != null && resource.exists()) {
						for (IContextChangeSet activeContextChangeSet : getActiveChangeSets()) {
							if (activeContextChangeSet instanceof ActiveChangeSet) {
								if (!((ActiveChangeSet) activeContextChangeSet).contains(resource)) {
									if (element.getInterest().isInteresting()) {
										((ActiveChangeSet) activeContextChangeSet).add(new IResource[] { resource });
									}
								}
							}
						}
						if (shouldRemove(element)) {
							for (ActiveChangeSetManager collector : changeSetManagers) {
								ChangeSet[] sets = collector.getSets();
								for (ChangeSet set : sets) {
									if (set instanceof ActiveChangeSet) {
										set.remove(resource);
									}
								}
							}
						}
					}
				}
			} catch (Exception e) {
				StatusHandler.log(new Status(IStatus.ERROR, FocusedTeamUiPlugin.ID_PLUGIN,
						"Could not manipulate change set resources", e)); //$NON-NLS-1$
			}
		}
	}

	public List<IContextChangeSet> getActiveChangeSets() {
		return new ArrayList<IContextChangeSet>(activeChangeSets);
	}

	private ITask getTask(IInteractionContext context) {
		return TasksUi.getTaskActivityManager().getActiveTask();
	}

	/**
	 * Ignores decay.
	 */
	private boolean shouldRemove(IInteractionElement element) {
		// TODO: generalize this logic?
		return (element.getInterest().getValue() + element.getInterest().getDecayValue()) < ContextCore.getCommonContextScaling()
				.getInteresting();
	}
}
