/*******************************************************************************
 * Copyright (c) 2006, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.core.subscribers;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.team.internal.core.Policy;

/**
 * A change set manager that batches change event notification.
 */
public class BatchingChangeSetManager extends ChangeSetManager {

	private ILock lock = Job.getJobManager().newLock();

	public static class CollectorChangeEvent {

		Set<ChangeSet> added = new HashSet<>();
		Set<ChangeSet> removed = new HashSet<>();
		Map<ChangeSet, IPath[]> changed = new HashMap<>();
		private final BatchingChangeSetManager collector;

		public CollectorChangeEvent(BatchingChangeSetManager collector) {
			this.collector = collector;
		}

		private void setAdded(ChangeSet set) {
			added.add(set);
			removed.remove(set);
		}

		private void setRemoved(ChangeSet set) {
			added.remove(set);
			removed.add(set);
			// Do not clear the changes list since clients may want to know what resources
			// were changed before the set was removed
		}

		private void changed(ChangeSet changeSet, IPath[] allAffectedResources) {
			if (added.contains(changeSet))
				return;
			IPath[] paths = changed.get(changeSet);
			if (paths == null) {
				changed.put(changeSet, allAffectedResources);
			} else {
				Set<IPath> allPaths = new HashSet<>();
				for (int i = 0; i < paths.length; i++) {
					IPath path = paths[i];
					allPaths.add(path);
				}
				for (int i = 0; i < allAffectedResources.length; i++) {
					IPath path = allAffectedResources[i];
					allPaths.add(path);
				}
				changed.put(changeSet, allPaths.toArray(new IPath[allPaths.size()]));
			}
		}

		public boolean isEmpty() {
			return changed.isEmpty() && added.isEmpty() && removed.isEmpty();
		}

		public ChangeSet[] getAddedSets() {
			return added.toArray(new ChangeSet[added.size()]);
		}

		public ChangeSet[] getRemovedSets() {
			return removed.toArray(new ChangeSet[removed.size()]);
		}

		public ChangeSet[] getChangedSets() {
			return changed.keySet().toArray(new ChangeSet[changed.size()]);
		}

		public IPath[] getChangesFor(ChangeSet set) {
			return changed.get(set);
		}

		public BatchingChangeSetManager getSource() {
			return collector;
		}
	}

	public static interface IChangeSetCollectorChangeListener {
		public void changeSetChanges(CollectorChangeEvent event, IProgressMonitor monitor);
	}

	private CollectorChangeEvent changes = new CollectorChangeEvent(this);

	public void beginInput() {
		lock.acquire();
	}

	public void endInput(IProgressMonitor monitor) {
		try {
			if (lock.getDepth() == 1) {
				// Remain locked while firing the events so the handlers
				// can expect the set to remain constant while they process the events
				fireChanges(Policy.monitorFor(monitor));
			}
		} finally {
			lock.release();
		}
	}

	private void fireChanges(final IProgressMonitor monitor) {
		if (changes.isEmpty()) {
			return;
		}
		final CollectorChangeEvent event = changes;
		changes = new CollectorChangeEvent(this);
		Object[] listeners = getListeners();
		for (int i = 0; i < listeners.length; i++) {
			final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i];
			if (listener instanceof IChangeSetCollectorChangeListener) {
				final IChangeSetCollectorChangeListener csccl = (IChangeSetCollectorChangeListener) listener;
				SafeRunner.run(new ISafeRunnable() {
					@Override
					public void handleException(Throwable exception) {
						// Exceptions are logged by the platform
					}
					@Override
					public void run() throws Exception {
						csccl.changeSetChanges(event, monitor);
					}
				});
			}
		}
	}

	@Override
	public void add(ChangeSet set) {
		try {
			beginInput();
			super.add(set);
			changes.setAdded(set);
		} finally {
			endInput(null);
		}
	}

	@Override
	public void remove(ChangeSet set) {
		try {
			beginInput();
			super.remove(set);
			changes.setRemoved(set);
		} finally {
			endInput(null);
		}
	}

	@Override
	protected void fireResourcesChangedEvent(ChangeSet changeSet, IPath[] allAffectedResources) {
		super.fireResourcesChangedEvent(changeSet, allAffectedResources);
		try {
			beginInput();
			changes.changed(changeSet, allAffectedResources);
		} finally {
			endInput(null);
		}
	}

	@Override
	protected void initializeSets() {
		// Nothing to do
	}
}
