/*******************************************************************************
 * Copyright (c) 2000, 2017 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.team.internal.core.subscribers;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.ITeamStatus;
import org.eclipse.team.core.TeamStatus;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.internal.core.*;

/**
 * A subscriber event handler whose output is a diff tree
 */
public class SubscriberDiffTreeEventHandler extends SubscriberEventHandler {

	// State constants for the event handler
	private static final int STATE_NEW = 0;
	public static final int STATE_STARTED = 1;
	private static final int STATE_OK_TO_INITIALIZE = 3;
	private static final int STATE_COLLECTING_CHANGES = 5;
	private static final int STATE_SHUTDOWN = 8;

	// state constants for exceptions
	private static final int EXCEPTION_NONE = 0;
	private static final int EXCEPTION_CANCELED = 1;
	private static final int EXCEPTION_ERROR = 2;

	private ResourceDiffTree tree;
	private SubscriberDiffCollector collector;
	private ISynchronizationScopeManager manager;
	private Object family;
	private DiffFilter filter;
	private int state = STATE_NEW;
	private int exceptionState = EXCEPTION_NONE;

	/*
	 * An event used to represent a change in a diff
	 */
	private class SubscriberDiffChangedEvent extends SubscriberEvent {
		private final IDiff node;

		public SubscriberDiffChangedEvent(IResource resource, int type, int depth, IDiff node) {
			super(resource, type, depth);
			this.node = node;
		}
		public IDiff getChangedNode() {
			return node;
		}
	}

	/*
	 * Collects resource and subscriber changes
	 */
	private class SubscriberDiffCollector extends SubscriberResourceCollector {

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

		@Override
		protected boolean hasMembers(IResource resource) {
			return tree.members(resource).length > 0;
		}

		@Override
		protected void remove(IResource resource) {
			SubscriberDiffTreeEventHandler.this.remove(resource);
		}

		@Override
		protected void change(IResource resource, int depth) {
			SubscriberDiffTreeEventHandler.this.change(resource, depth);
		}
	}

	/**
	 * Create the handler
	 * @param subscriber the subscriber for the handler
	 * @param manager the scope of the handler
	 * @param tree the tree to be populated by this handler
	 * @param filter a filter
	 */
	public SubscriberDiffTreeEventHandler(Subscriber subscriber, ISynchronizationScopeManager manager, ResourceDiffTree tree, DiffFilter filter) {
		super(subscriber, manager.getScope());
		this.manager = manager;
		this.tree = tree;
		this.collector = new SubscriberDiffCollector(subscriber);
		this.filter = filter;
	}

	@Override
	protected void reset(ResourceTraversal[] traversals, int type) {
		// Reset the exception state since we are reseting
		exceptionState = EXCEPTION_NONE;
		if (!manager.isInitialized() && state == STATE_OK_TO_INITIALIZE) {
			// This means the scope has not been initialized
			queueEvent(new RunnableEvent(monitor -> {
				// Only initialize the scope if we are in the STARTED state
				if (state == STATE_OK_TO_INITIALIZE) {
					try {
						prepareScope(monitor);
						state = STATE_COLLECTING_CHANGES;
					} finally {
						// If the initialization didn't complete,
						// return to the STARTED state.
						if (state != STATE_COLLECTING_CHANGES) {
							state = STATE_STARTED;
							if (exceptionState == EXCEPTION_NONE)
								exceptionState = EXCEPTION_CANCELED;
						}
					}
				}
			}, true), true);
		} else if (manager.isInitialized()) {
			state = STATE_COLLECTING_CHANGES;
			super.reset(traversals, type);
		}
	}

	public void reset(){
		reset(getScope().getTraversals(),
				SubscriberEventHandler.SubscriberEvent.INITIALIZE);
	}

	protected void prepareScope(IProgressMonitor monitor) {
		try {
			manager.initialize(monitor);
		} catch (CoreException e) {
			handleException(e);
		}
		ResourceTraversal[] traversals = manager.getScope().getTraversals();
		if (traversals.length > 0)
			reset(traversals, SubscriberEvent.INITIALIZE);
	}

	@Override
	protected void handleChange(IResource resource) throws CoreException {
		IDiff node = getSubscriber().getDiff(resource);
		if (node == null) {
			queueDispatchEvent(
				new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO));
		} else {
			if (isInScope(resource))
				queueDispatchEvent(
					new SubscriberDiffChangedEvent(resource, SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, node));
		}
	}

	private boolean isInScope(IResource resource) {
		return manager.getScope().contains(resource);
	}

	@Override
	protected void collectAll(IResource resource, int depth,
			final IProgressMonitor monitor) {
		Policy.checkCanceled(monitor);
		monitor.beginTask(null, IProgressMonitor.UNKNOWN);
		ResourceTraversal[] traversals = new ResourceTraversal[] { new ResourceTraversal(new IResource[] { resource }, depth, IResource.NONE) };
		try {
			getSubscriber().accept(traversals, diff -> {
				Policy.checkCanceled(monitor);
				monitor.subTask(NLS.bind(Messages.SubscriberDiffTreeEventHandler_0, tree.getResource(diff).getFullPath().toString()));
				// Queue up any found diffs for inclusion into the output tree
				queueDispatchEvent(
						new SubscriberDiffChangedEvent(tree.getResource(diff), SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, diff));
				// Handle any pending dispatches
				handlePreemptiveEvents(monitor);
				handlePendingDispatch(monitor);
				return true;
			});
		} catch (CoreException e) {
			if (resource.getProject().isAccessible())
				handleException(e, resource, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage());
		} finally {
			monitor.done();
		}
	}

	@Override
	protected void dispatchEvents(SubscriberEvent[] events,
			IProgressMonitor monitor) {
		try {
        	tree.beginInput();
			for (int i = 0; i < events.length; i++) {
				SubscriberEvent event = events[i];
				switch (event.getType()) {
					case SubscriberEvent.CHANGE :
						if (event instanceof SubscriberDiffChangedEvent) {
							SubscriberDiffChangedEvent se = (SubscriberDiffChangedEvent) event;
							IDiff changedNode = se.getChangedNode();
							if (changedNode.getKind() == IDiff.NO_CHANGE) {
								tree.remove(changedNode.getPath());
							} else {
								addDiff(changedNode, monitor);
							}
						}
						break;
					case SubscriberEvent.REMOVAL :
						IDiff[] nodesToRemove = tree.getDiffs(new ResourceTraversal[] { event.asTraversal() });
						for (int j = 0; j < nodesToRemove.length; j++) {
							IDiff node = nodesToRemove[j];
							tree.remove(node.getPath());
						}
						break;
				}
			}
		} finally {
			tree.endInput(monitor);
		}
	}

	private void addDiff(IDiff diff, IProgressMonitor monitor) {
		if (filter == null || filter.select(diff, monitor)) {
			tree.add(diff);
		} else {
			tree.remove(diff.getPath());
		}
	}

	/**
	 * Return the resource diff tree that contains the out-of-sync diffs for the
	 * subscriber.
	 * @return the resource diff tree
	 */
	public IResourceDiffTree getTree() {
		return tree;
	}

	@Override
	public Subscriber getSubscriber() {
		return super.getSubscriber();
	}

	@Override
	public void shutdown() {
		state = STATE_SHUTDOWN;
		collector.dispose();
		super.shutdown();
	}

	@Override
	protected Object getJobFamiliy() {
		return family;
	}

	/**
	 * Set the family of this handler to the given object
	 * @param family the family of the handler's job
	 */
	public void setJobFamily(Object family) {
		this.family = family;
	}

	@Override
	protected void handleException(CoreException e, IResource resource, int code, String message) {
		super.handleException(e, resource, code, message);
		tree.reportError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, code, message, e, resource));
		exceptionState = EXCEPTION_ERROR;
	}

	@Override
	protected void handleCancel(OperationCanceledException e) {
		super.handleCancel(e);
		tree.reportError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_CANCELLATION, Messages.SubscriberEventHandler_12, e, ResourcesPlugin.getWorkspace().getRoot()));
		if (exceptionState == EXCEPTION_NONE)
			exceptionState = EXCEPTION_CANCELED;
	}

	public DiffFilter getFilter() {
		return filter;
	}

	public void setFilter(DiffFilter filter) {
		this.filter = filter;
	}

	/**
	 * If the handler is not initialized or not in the process
	 * of initializing, start the initialization process.
	 */
	public synchronized void initializeIfNeeded() {
		if (state == STATE_STARTED) {
			state = STATE_OK_TO_INITIALIZE;
			reset(getScope().getTraversals(), SubscriberEvent.INITIALIZE);
		} else if (exceptionState != EXCEPTION_NONE) {
			reset(getScope().getTraversals(), SubscriberEvent.INITIALIZE);
		}
	}

	@Override
	public synchronized void start() {
		super.start();
		if (state == STATE_NEW)
			state = STATE_STARTED;
	}

	public int getState() {
		return state;
	}

	@Override
	protected boolean isSystemJob() {
		if (manager != null && !manager.isInitialized())
			return false;
		return super.isSystemJob();
	}

	@Override
	public synchronized void remove(IResource resource) {
		// Don't queue changes if we haven't been initialized
		if (state == STATE_STARTED)
			return;
		super.remove(resource);
	}

	@Override
	public void change(IResource resource, int depth) {
		// Don't queue changes if we haven't been initialized
		if (state == STATE_STARTED)
			return;
		super.change(resource, depth);
	}
}
