/*******************************************************************************
 * Copyright (c) 2000, 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.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.internal.core.BackgroundEventHandler;
import org.eclipse.team.internal.core.Messages;
import org.eclipse.team.internal.core.Policy;
import org.eclipse.team.internal.core.TeamPlugin;
import org.osgi.service.prefs.Preferences;

/**
 * This class manages the active change sets associated with a subscriber.
 */
public class SubscriberChangeSetManager extends ActiveChangeSetManager {

	private static final String PREF_CHANGE_SETS = "changeSets"; //$NON-NLS-1$

	private static final int RESOURCE_REMOVAL = 1;
	private static final int RESOURCE_CHANGE = 2;

	private EventHandler handler;
	private ResourceCollector collector;

	/*
	 * Background event handler for serializing and batching change set changes
	 */
	private class EventHandler extends BackgroundEventHandler {

		private List<Event> dispatchEvents = new ArrayList<>();

		protected EventHandler(String jobName, String errorTitle) {
			super(jobName, errorTitle);
		}

		@Override
		protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException {
			// Handle everything in the dispatch
			if (isShutdown())
				throw new OperationCanceledException();
			dispatchEvents.add(event);
		}

		@Override
		protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException {
			if (dispatchEvents.isEmpty()) {
				return false;
			}
			if (isShutdown())
				throw new OperationCanceledException();
			ResourceDiffTree[] locked = null;
			try {
				locked = beginDispath();
				for (Iterator iter = dispatchEvents.iterator(); iter.hasNext();) {
					Event event = (Event) iter.next();
					switch (event.getType()) {
					case RESOURCE_REMOVAL:
						handleRemove(event.getResource());
						break;
					case RESOURCE_CHANGE:
						handleChange(event.getResource(), ((ResourceEvent)event).getDepth());
						break;
					default:
						break;
					}
					if (isShutdown())
						throw new OperationCanceledException();
				}
			} catch (CoreException e) {
				throw TeamException.asTeamException(e);
			} finally {
				try {
					endDispatch(locked, monitor);
				} finally {
					dispatchEvents.clear();
				}
			}
			return true;
		}

		/*
		 * Begin input on all the sets and return the sync sets that were
		 * locked. If this method throws an exception then the client
		 * can assume that no sets were locked
		 */
		private ResourceDiffTree[] beginDispath() {
			ChangeSet[] sets = getSets();
			List<ResourceDiffTree> lockedSets = new ArrayList<>();
			try {
				for (int i = 0; i < sets.length; i++) {
					ActiveChangeSet set = (ActiveChangeSet)sets[i];
					ResourceDiffTree tree = set.internalGetDiffTree();
					lockedSets.add(tree);
					tree.beginInput();
				}
				return lockedSets.toArray(new ResourceDiffTree[lockedSets.size()]);
			} catch (RuntimeException e) {
				try {
					for (Iterator iter = lockedSets.iterator(); iter.hasNext();) {
						ResourceDiffTree tree = (ResourceDiffTree) iter.next();
						try {
							tree.endInput(null);
						} catch (Throwable e1) {
							// Ignore so that original exception is not masked
						}
					}
				} catch (Throwable e1) {
					// Ignore so that original exception is not masked
				}
				throw e;
			}
		}

		private void endDispatch(ResourceDiffTree[] locked, IProgressMonitor monitor) {
			if (locked == null) {
				// The begin failed so there's nothing to unlock
				return;
			}
			monitor.beginTask(null, 100 * locked.length);
			for (int i = 0; i < locked.length; i++) {
				ResourceDiffTree tree = locked[i];
				try {
					tree.endInput(Policy.subMonitorFor(monitor, 100));
				} catch (RuntimeException e) {
					// Don't worry about ending every set if an error occurs.
					// Instead, log the error and suggest a restart.
					TeamPlugin.log(IStatus.ERROR, Messages.SubscriberChangeSetCollector_0, e);
					throw e;
				}
			}
			monitor.done();
		}

		@Override
		protected synchronized void queueEvent(Event event, boolean front) {
			// Override to allow access from enclosing class
			super.queueEvent(event, front);
		}

		/*
		 * Handle the removal
		 */
		private void handleRemove(IResource resource) {
			ChangeSet[] sets = getSets();
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				// This will remove any descendants from the set and callback to
				// resourcesChanged which will batch changes
				if (!set.isEmpty()) {
					set.rootRemoved(resource, IResource.DEPTH_INFINITE);
					if (set.isEmpty()) {
						remove(set);
					}
				}
			}
		}

		/*
		 * Handle the change
		 */
		private void handleChange(IResource resource, int depth) throws CoreException {
			IDiff diff = getDiff(resource);
			if (isModified(diff)) {
				ActiveChangeSet[] containingSets = getContainingSets(resource);
				if (containingSets.length == 0) {
					// Consider for inclusion in the default set
					// if the resource is not already a member of another set
					if (getDefaultSet() != null) {
						getDefaultSet().add(diff);
					}
				} else {
					for (int i = 0; i < containingSets.length; i++) {
						ActiveChangeSet set = containingSets[i];
						// Update the sync info in the set
						set.add(diff);
					}
				}
			} else {
				removeFromAllSets(resource);
			}
			if (depth != IResource.DEPTH_ZERO) {
				IResource[] members = getSubscriber().members(resource);
				for (int i = 0; i < members.length; i++) {
					IResource member = members[i];
					handleChange(member, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE);
				}
			}
		}

		private void removeFromAllSets(IResource resource) {
			List<ChangeSet> toRemove = new ArrayList<>();
			ChangeSet[] sets = getSets();
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				if (set.contains(resource)) {
					set.remove(resource);
					if (set.isEmpty()) {
						toRemove.add(set);
					}
				}
			}
			for (Object element : toRemove) {
				ActiveChangeSet set = (ActiveChangeSet) element;
				remove(set);
			}
		}

		private ActiveChangeSet[] getContainingSets(IResource resource) {
			Set<ActiveChangeSet> result = new HashSet<>();
			ChangeSet[] sets = getSets();
			for (int i = 0; i < sets.length; i++) {
				ChangeSet set = sets[i];
				if (set.contains(resource)) {
					result.add((ActiveChangeSet) set);
				}
			}
			return result.toArray(new ActiveChangeSet[result.size()]);
		}
	}

	private class ResourceCollector extends SubscriberResourceCollector {

		public ResourceCollector(Subscriber subscriber) {
			super(subscriber);
		}

		@Override
		protected void remove(IResource resource) {
			if (handler != null)
				handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_REMOVAL, IResource.DEPTH_INFINITE), false);
		}

		@Override
		protected void change(IResource resource, int depth) {
			if (handler != null)
				handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_CHANGE, depth), false);
		}

		@Override
		protected boolean hasMembers(IResource resource) {
			return SubscriberChangeSetManager.this.hasMembers(resource);
		}
	}

	public SubscriberChangeSetManager(Subscriber subscriber) {
		collector = new ResourceCollector(subscriber);
		handler = new EventHandler(NLS.bind(Messages.SubscriberChangeSetCollector_1, new String[] { subscriber.getName() }), NLS.bind(Messages.SubscriberChangeSetCollector_2, new String[] { subscriber.getName() })); //
	}

	@Override
	protected void initializeSets() {
		load(getPreferences());
	}

	public boolean hasMembers(IResource resource) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ActiveChangeSet set = (ActiveChangeSet)sets[i];
			if (set.getDiffTree().getChildren(resource.getFullPath()).length > 0)
				return true;
		}
		if (getDefaultSet() != null)
			return (getDefaultSet().getDiffTree().getChildren(resource.getFullPath()).length > 0);
		return false;
	}

	/**
	 * Return the sync info for the given resource obtained
	 * from the subscriber.
	 * @param resource the resource
	 * @return the sync info for the resource
	 * @throws CoreException
	 */
	@Override
	public IDiff getDiff(IResource resource) throws CoreException {
		Subscriber subscriber = getSubscriber();
		return subscriber.getDiff(resource);
	}

	/**
	 * Return the subscriber associated with this collector.
	 * @return the subscriber associated with this collector
	 */
	public Subscriber getSubscriber() {
		return collector.getSubscriber();
	}

	@Override
	public void dispose() {
		handler.shutdown();
		collector.dispose();
		super.dispose();
		save(getPreferences());
	}

	private Preferences getPreferences() {
		return getParentPreferences().node(getSubscriberIdentifier());
	}

	private static Preferences getParentPreferences() {
		return getTeamPreferences().node(PREF_CHANGE_SETS);
	}

	private static Preferences getTeamPreferences() {
		return InstanceScope.INSTANCE.getNode(TeamPlugin.getPlugin().getBundle().getSymbolicName());
	}

	/**
	 * Return the id that will uniquely identify the subscriber across
	 * restarts.
	 * @return the id that will uniquely identify the subscriber across
	 */
	protected String getSubscriberIdentifier() {
		return getSubscriber().getName();
	}

	/**
	 * Wait until the collector is done processing any events.
	 * This method is for testing purposes only.
	 * @param monitor
	 */
	public void waitUntilDone(IProgressMonitor monitor) {
		monitor.worked(1);
		// wait for the event handler to process changes.
		while(handler.getEventHandlerJob().getState() != Job.NONE) {
			monitor.worked(1);
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			Policy.checkCanceled(monitor);
		}
		monitor.worked(1);
	}

	@Override
	protected String getName() {
		return getSubscriber().getName();
	}
}
