/*******************************************************************************
 * 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.core.subscribers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.*;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.core.variants.IResourceVariantComparator;
import org.eclipse.team.internal.core.*;
import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;

/**
 * A Subscriber provides synchronization between local resources and a
 * remote location that is used to share those resources.
 * <p>
 * When queried for the <code>SyncInfo</code> corresponding to a local resource using
 * <code>getSyncInfo(IResource)</code>, the subscriber should not contact the server.
 * Server round trips should only occur within the <code>refresh</code>
 * method of the subscriber. Consequently,
 * the implementation of a subscriber must cache enough state information for a remote resource to calculate the
 * synchronization state without contacting the server.  During a refresh, the latest remote resource state
 * information should be fetched and cached. For
 * a subscriber that supports three-way compare, the refresh should also fetch the latest base state unless this is
 * available by some other means (e.g. for some repository tools, the base state is persisted on disk with the
 * local resources).
 * </p>
 * <p>
 * After a refresh, the subscriber must notify any listeners of local resources whose corresponding remote resource
 * or base resource changed. The subscriber does not need to notify listeners when the state changes due to a local
 * modification since local changes are available through the <code>IResource</code> delta mechanism. However,
 * the subscriber must
 * cache enough information (e.g. the local timestamp of when the file was in-sync with its corresponding remote
 * resource)
 * to determine if the file represents an outgoing change so that <code>SyncInfo</code> obtained
 * after a delta will indicate that the file has an outgoing change. The subscriber must also notify listeners
 * when roots are added
 * or removed. For example, a subscriber for a repository provider would fire a root added event when a project
 * was shared
 * with a repository. No event is required when a root is deleted as this is available through the
 * <code>IResource</code> delta mechanism. It is up to clients to re-query the subscriber
 * when the state of a resource changes locally by listening to <code>IResource</code> deltas.
 * </p><p>
 * The remote and base states can also include the state for resources that do not exist locally (i.e outgoing deletions
 * or incoming additions). When queried for the members of a local resource, the subscriber should include any children
 * for which a remote exists even if the local does not.
 * </p>
 * @since 3.0
 */
abstract public class Subscriber {

	private List<ISubscriberChangeListener> listeners = new ArrayList<>(1);

	/**
	 * Return the name of this subscription, in a format that is
	 * suitable for display to an end user.
	 *
	 * @return String representing the name of this subscription.
	 */
	abstract public String getName();

	/**
	 * Returns <code>true</code> if this resource is supervised by this
	 * subscriber. A supervised resource is one for which this subscriber
	 * maintains the synchronization state. Supervised resources are the only
	 * resources returned when <code>members(IResource)</code> was invoked with the parent
	 * of the resource. Returns <code>false</code> in all
	 * other cases.
	 *
	 * @param resource the resource being tested
	 * @return <code>true</code> if this resource is supervised, and <code>false</code>
	 *               otherwise
	 * @throws TeamException
	 */
	abstract public boolean isSupervised(IResource resource) throws TeamException;

	/**
	 * Returns all non-transient member resources of the given resource. The
	 * result will include entries for resources that exist either in the
	 * workspace or are implicated in an incoming change. Returns an empty list
	 * if the given resource exists neither in the workspace nor in the
	 * corresponding subscriber location, or if the given resource is transient.
	 * <p>
	 * This is a fast operation; the repository is not contacted.
	 * </p>
	 * @param resource the resource
	 * @return a list of member resources
	 * @throws TeamException
	 */
	abstract public IResource[] members(IResource resource) throws TeamException;

	/**
	 * Returns the list of root resources this subscriber considers for
	 * synchronization. A client should call this method first then can safely
	 * call <code>members</code> to navigate the resources managed by this
	 * subscriber.
	 *
	 * @return a list of resources
	 */
	abstract public IResource[] roots();

	/**
	 * Returns synchronization info for the given resource, or <code>null</code>
	 * if there is no synchronization info because the subscriber does not apply
	 * to this resource.
	 * <p>
	 * Note that sync info may be returned for non-existing or for resources
	 * which have no corresponding remote resource.
	 * </p>
	 * <p>
	 * This method will be quick. If synchronization calculation requires
	 * content from the server it must be cached when the subscriber is
	 * refreshed. A client should call refresh before calling this method to
	 * ensure that the latest information is available for computing the sync
	 * state.
	 * </p>
	 * <p>
	 * The sync-info node returned by this method does not fully describe
	 * all types of changes. A more descriptive change can be obtained from
	 * the {@link #getDiff(IResource) } method.
	 *
	 * @param resource the resource of interest
	 * @return sync info
	 * @throws TeamException
	 * @see #getDiff(IResource)
	 */
	abstract public SyncInfo getSyncInfo(IResource resource) throws TeamException;

	/**
	 * Returns the comparison criteria that will be used by the sync info
	 * created by this subscriber.
	 *
	 * @return the comparator to use when computing sync states for this
	 * subscriber.
	 */
	abstract public IResourceVariantComparator getResourceComparator();

	/**
	 * Refreshes the resource hierarchy from the given resources and their
	 * children (to the specified depth) from the corresponding resources in the
	 * remote location. Resources are ignored in the following cases:
	 * <ul>
	 * <li>if they do not exist either in the workspace or in the corresponding
	 * remote location</li>
	 * <li>if the given resource is not supervised by this subscriber</li>
	 * <li>if the given resource is a closed project (they are ineligible for
	 * synchronization)</li>
	 * </ul>
	 * <p>
	 * Typical synchronization operations use the statuses computed by this
	 * method as the basis for determining what to do. It is possible for the
	 * actual sync status of the resource to have changed since the current
	 * local sync status was refreshed. Operations typically skip resources with
	 * stale sync information. The chances of stale information being used can
	 * be reduced by running this method (where feasible) before doing other
	 * operations. Note that this will of course affect performance.
	 * </p>
	 * <p>
	 * The depth parameter controls whether refreshing is performed on just the
	 * given resource (depth= <code>DEPTH_ZERO</code>), the resource and its
	 * children (depth= <code>DEPTH_ONE</code>), or recursively to the
	 * resource and all its descendents (depth= <code>DEPTH_INFINITE</code>).
	 * Use depth <code>DEPTH_ONE</code>, rather than depth
	 * <code>DEPTH_ZERO</code>, to ensure that new members of a project or
	 * folder are detected.
	 * </p>
	 * <p>
	 * This method might change resources; any changes will be reported in a
	 * subsequent subscriber resource change event indicating changes to server
	 * sync status.
	 * </p>
	 * <p>
	 * This method contacts the server and is therefore long-running; progress
	 * and cancellation are provided by the given progress monitor.
	 * </p>
	 * @param resources the resources
	 * @param depth valid values are <code>DEPTH_ZERO</code>,
	 * <code>DEPTH_ONE</code>, or <code>DEPTH_INFINITE</code>
	 * @param monitor progress monitor, or <code>null</code> if progress
	 * reporting and cancellation are not desired
	 * @exception TeamException if this method fails. Reasons include:
	 * <ul>
	 * <li>The server could not be contacted.</li>
	 * </ul>
	 */
	abstract public void refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException;

	/**
	 * Adds a listener to this team subscriber. Has no effect if an identical
	 * listener is already registered.
	 * <p>
	 * Team resource change listeners are informed about state changes that
	 * affect the resources supervised by this subscriber.
	 * </p>
	 * @param listener a team resource change listener
	 */
	public void addListener(ISubscriberChangeListener listener) {
		synchronized (listeners) {
			if (!listeners.contains(listener)) {
				listeners.add(listener);
			}
		}
	}

	/**
	 * Removes a listener previously registered with this team subscriber. Has
	 * no effect if an identical listener is not registered.
	 *
	 * @param listener a team resource change listener
	 */
	public void removeListener(ISubscriberChangeListener listener) {
		synchronized (listeners) {
			listeners.remove(listener);
		}
	}

	/**
	 * Adds all out-of-sync resources (<code>getKind() != SyncInfo.IN_SYNC</code>) that occur
	 * under the given resources to the specified depth. The purpose of this
	 * method is to provide subscribers a means of optimizing the determination
	 * of all out-of-sync descendants of a set of resources.
	 * <p>
	 * If any of the directly provided resources are not supervised by the subscriber, then
	 * they should be removed from the set.
	 * If errors occur while determining the sync info for the resources, they should
	 * be added to the set using <code>SyncInfoSet.addError</code>.
	 * </p>
	 * @param resources the root of the resource subtrees from which out-of-sync sync info should be collected
	 * @param depth the depth to which sync info should be collected
	 * (one of <code>IResource.DEPTH_ZERO</code>,
	 * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
	 * @param set the sync info set to which out-of-sync resources should be added (or removed). Any errors
	 * should be added to the set as well.
	 * @param monitor a progress monitor
	 */
	public void collectOutOfSync(IResource[] resources, int depth, SyncInfoSet set, IProgressMonitor monitor) {
		try {
			monitor.beginTask(null, 100 * resources.length);
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				IProgressMonitor subMonitor = Policy.subMonitorFor(monitor, 100);
				subMonitor.beginTask(null, IProgressMonitor.UNKNOWN);
				collect(resource, depth, set, subMonitor);
				subMonitor.done();
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Fires a team resource change event to all registered listeners. Only
	 * listeners registered at the time this method is called are notified.
	 * Listener notification makes use of an <code>ISafeRunnable</code> to ensure that
	 * client exceptions do not affect the notification to other clients.
	 */
	protected void fireTeamResourceChange(final ISubscriberChangeEvent[] deltas) {
		ISubscriberChangeListener[] allListeners;
		// Copy the listener list so we're not calling client code while synchronized
		synchronized (listeners) {
			allListeners = listeners.toArray(new ISubscriberChangeListener[listeners.size()]);
		}
		// Notify the listeners safely so all will receive notification
		for (int i = 0; i < allListeners.length; i++) {
			final ISubscriberChangeListener listener = allListeners[i];
			SafeRunner.run(new ISafeRunnable() {
				@Override
				public void handleException(Throwable exception) {
					// don't log the exception....it is already being logged in
					// Platform#run
				}
				@Override
				public void run() throws Exception {
					listener.subscriberResourceChanged(deltas);
				}
			});
		}
	}

	/*
	 * Collect the calculated synchronization information for the given resource at the given depth. The
	 * results are added to the provided list.
	 */
	private void collect(
		IResource resource,
		int depth,
		SyncInfoSet set,
		IProgressMonitor monitor) {

		Policy.checkCanceled(monitor);

		if (resource.getType() != IResource.FILE
			&& depth != IResource.DEPTH_ZERO) {
			try {
				IResource[] members = members(resource);
				for (int i = 0; i < members.length; i++) {
					collect(
						members[i],
						depth == IResource.DEPTH_INFINITE
							? IResource.DEPTH_INFINITE
							: IResource.DEPTH_ZERO,
						set,
						monitor);
				}
			} catch (TeamException e) {
				set.addError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_ERROR, NLS.bind(Messages.SubscriberEventHandler_8, new String[] { resource.getFullPath().toString(), e.getMessage() }), e, resource));
			}
		}

		monitor.subTask(NLS.bind(Messages.SubscriberEventHandler_2, new String[] { resource.getFullPath().toString() }));
		try {
			SyncInfo info = getSyncInfo(resource);
			if (info == null || info.getKind() == SyncInfo.IN_SYNC) {
				// Resource is no longer under the subscriber control.
				// This can occur for the resources past as arguments to collectOutOfSync
				set.remove(resource);
			} else {
				set.add(info);
			}
		} catch (TeamException e) {
			set.addError(new TeamStatus(
					IStatus.ERROR, TeamPlugin.ID, ITeamStatus.RESOURCE_SYNC_INFO_ERROR,
					NLS.bind(Messages.SubscriberEventHandler_9, new String[] { resource.getFullPath().toString(), e.getMessage() }),
					e, resource));
		}
		// Tick the monitor to give the owner a chance to do something
		monitor.worked(1);
	}

	/**
	 * Returns synchronization info, in the form of an {@link IDiff} for the
	 * given resource, or <code>null</code> if there is no synchronization
	 * info because the subscriber does not apply to this resource or the resource
	 * is in-sync.
	 * <p>
	 * Note that a diff may be returned for non-existing or for resources
	 * which have no corresponding remote resource.
	 * </p>
	 * <p>
	 * This method will be quick. If synchronization calculation requires
	 * content from the server it must be cached when the subscriber is
	 * refreshed. A client should call refresh before calling this method to
	 * ensure that the latest information is available for computing the diff.
	 * </p>
	 * <p>
	 * The diff node returned by this method describes the changes associated
	 * with the given resource in more detail than the sync-info returned
	 * by calling {@link #getSyncInfo(IResource) }.
	 *
	 * @param resource the resource of interest
	 * @return the diff for the resource or <code>null</code>
	 * @throws CoreException
	 * @throws TeamException if errors occur
	 * @since 3.2
	 */
	public IDiff getDiff(IResource resource) throws CoreException {
		SyncInfo info = getSyncInfo(resource);
		if (info == null || info.getKind() == SyncInfo.IN_SYNC)
			return null;
		return SyncInfoToDiffConverter.getDefault().getDeltaFor(info);
	}

	/**
	 * Visit any out-of-sync resources covered by the given traversals. Any resources
	 * covered by the traversals are ignored in the following cases:
	 * <ul>
	 * <li>if they do not exist either in the workspace or in the corresponding
	 * remote location</li>
	 * <li>if the given resource is not supervised by this subscriber</li>
	 * <li>if the given resource is a closed project (they are ineligible for
	 * synchronization)</li>
	 * </ul>
	 * @param traversals the traversals to be visited
	 * @param visitor the visitor
	 * @throws CoreException
	 * @throws TeamException if errors occur
	 * @since 3.2
	 */
	public void accept(ResourceTraversal[] traversals, IDiffVisitor visitor) throws CoreException {
		for (int i = 0; i < traversals.length; i++) {
			ResourceTraversal traversal = traversals[i];
			accept(traversal.getResources(), traversal.getDepth(), visitor);
		}
	}

	/**
	 * Visit any out-of-sync resources in the given resources visited to the
	 * given depth. Resources are ignored in the following cases:
	 * <ul>
	 * <li>if they do not exist either in the workspace or in the corresponding
	 * remote location</li>
	 * <li>if the given resource is not supervised by this subscriber</li>
	 * <li>if the given resource is a closed project (they are ineligible for
	 * synchronization)</li>
	 * </ul>
	 *
	 * @param resources the root of the resource subtrees from which out-of-sync
	 *            sync info should be visited
	 * @param depth the depth to which sync info should be collected (one of
	 *            <code>IResource.DEPTH_ZERO</code>,
	 *            <code>IResource.DEPTH_ONE</code>, or
	 *            <code>IResource.DEPTH_INFINITE</code>)
	 * @param visitor the visitor
	 * @throws CoreException if errors occur
	 * @since 3.2
	 */
	public void accept(IResource[] resources, int depth, IDiffVisitor visitor) throws CoreException {
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			accept(resource, depth, visitor);
		}
	}

	private void accept(IResource resource, int depth, IDiffVisitor visitor) throws CoreException {
		IDiff node = getDiff(resource);
		if (node != null && node.getKind() != IDiff.NO_CHANGE) {
			if (!visitor.visit(node))
				return;
		}
		if (depth != IResource.DEPTH_ZERO) {
			IResource[] members = members(resource);
			int newDepth = depth == IResource.DEPTH_INFINITE ? IResource.DEPTH_INFINITE : IResource.DEPTH_ZERO;
			for (int i = 0; i < members.length; i++) {
				IResource member = members[i];
				accept(member, newDepth, visitor);
			}
		}
	}

	/**
	 * Refresh the subscriber for the given traversals. By default this method calls
	 * {@link #refresh(IResource[], int, IProgressMonitor) } for each traversal. Any resources
	 * covered by the traversals are ignored in the following cases:
	 * <ul>
	 * <li>if they do not exist either in the workspace or in the corresponding
	 * remote location</li>
	 * <li>if the given resource is not supervised by this subscriber</li>
	 * <li>if the given resource is a closed project (they are ineligible for
	 * synchronization)</li>
	 * </ul>
	 * <p>
	 * Subclasses may override.
	 * @param traversals the traversals to be refreshed
	 * @param monitor a progress monitor
	 * @throws TeamException if errors occur
	 * @since 3.2
	 */
	public void refresh(ResourceTraversal[] traversals, IProgressMonitor monitor) throws TeamException {
		monitor.beginTask(null, 100 * traversals.length);
		for (int i = 0; i < traversals.length; i++) {
			ResourceTraversal traversal = traversals[i];
			refresh(traversal.getResources(), traversal.getDepth(), Policy.subMonitorFor(monitor, 100));
		}
		monitor.done();
	}

	/**
	 * Return the synchronization state of the given resource mapping.
	 * Only return the portion of the synchronization state that matches
	 * the provided <code>stateMask</code>. The synchronization state flags that are
	 * guaranteed to be interpreted by this method are:
	 * <ul>
	 * <li>The kind flags {@link IDiff#ADD}, {@link IDiff#REMOVE} and {@link IDiff#CHANGE}.
	 * If none of these flags are included then all are assumed.
	 * <li>The direction flags {@link IThreeWayDiff#INCOMING} and {@link IThreeWayDiff#OUTGOING} if the
	 * subscriber is a three-way subscriber. If neither are provided, both are assumed.
	 * </ul>
	 * Other flags can be included and may or may not be interpreted by the subscriber.
	 * <p>
	 * An element will only include {@link IDiff#ADD} in the returned state if all resources covered
	 * by the traversals mappings are added. Similarly, {@link IDiff#REMOVE} will only be included
	 * if all the resources covered by the traversals are deleted. Otherwise {@link IDiff#CHANGE}
	 * will be returned.
	 *
	 * @param mapping the resource mapping whose synchronization state is to be determined
	 * @param stateMask the mask that identifies the state flags of interested
	 * @param monitor a progress monitor
	 * @return the synchronization state of the given resource mapping
	 * @throws CoreException
	 * @since 3.2
	 * @see IDiff
	 * @see IThreeWayDiff
	 */
	public int getState(ResourceMapping mapping, int stateMask, IProgressMonitor monitor) throws CoreException {
		ResourceTraversal[] traversals = mapping.getTraversals(new SubscriberResourceMappingContext(this, true), monitor);
		final int[] direction = new int[] { 0 };
		final int[] kind = new int[] { 0 };
		accept(traversals, new IDiffVisitor() {
			@Override
			public boolean visit(IDiff diff) {
				if (diff instanceof IThreeWayDiff) {
					IThreeWayDiff twd = (IThreeWayDiff) diff;
					direction[0] |= twd.getDirection();
				}
				// If the traversals contain a combination of kinds, return a CHANGE
				int diffKind = diff.getKind();
				if (kind[0] == 0)
					kind[0] = diffKind;
				if (kind[0] != diffKind) {
					kind[0] = IDiff.CHANGE;
				}
				// Only need to visit the children of a change
				return diffKind == IDiff.CHANGE;
			}
		});
		return (direction[0] | kind[0]) & stateMask;
	}
}
