/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-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.runtime.*;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.sync.IRemoteResource;

/**
 * A TeamSubscriber provides synchronization between local resources and a remote location 
 * that is used to share those resources. 
 * 
 * [Note: How can we allow the refresh() operation to optimize the sync calculation based
 * on the currently configured compare criteria?]
 */
abstract public class TeamSubscriber {
	
	private List listeners = new ArrayList(1);
	
	/**
	 * Return the description of this subscription, in a format that is suitable for 
	 * display to an end user. The description should contain enough details to
	 * understand the connection type of this subscriber. 
	 * 
	 * @return String representing the description of this subscription. 
	 */
	abstract public String getDescription();
	
	/**
	 * 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.  Returns <code>false</code> in all other cases. 
	 * 
	 * @return <code>true</code> if this resource is supervised, and 
	 *   <code>false</code> otherwise
	 */
	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 team stream, or if the
	 * given resource is transient.
	 * <p>
	 * This is a fast operation; the repository is not contacted.
	 * </p>
	 * <p>
	 * [Issue1 : Is there any filtering on the members? Just the ones
	 *  that changed in some way, or *every member*?
	 * ]</p>
	 *
	 * @param resource the resource
	 * @return a list of member resources
	 * @exception CoreException if this request fails. Reasons include:
	 */
	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
	 * @throws TeamException
	 */
	abstract public IResource[] roots();
	
	/**
	 * Returns a handle to the remote resource corresponding to the given
	 * resource, or <code>null</code> if there is no corresponding resource
	 * edition. 
	 * <p> 
	 * This is a fast operation; the repository is not contacted.
	 * </p>
	 *
	 * @param resource the resource
	 * @return a server resource
	 * @exception CoreException if this request fails. Reasons include:
	 * <ul>
	 * <li>???</li>
	 * </ul>
	 */	
	abstract public IRemoteResource getRemoteResource(IResource resource) throws TeamException;
	
	/**
	 * 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 may take some time; it depends on the comparison criteria
	 * that is used to calculate the synchronization state (e.g. using content
	 * or only timestamps).
	 * </p>
	 *
	 * @param resource the resource of interest
	 * @return sync info
	 */
	abstract public SyncInfo getSyncInfo(IResource resource, IProgressMonitor monitor) throws TeamException; 
	
	/** 
	 * 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 marked as derived (see IResource#isDerived())</li>
	 * <li>if the given resource is not managed by this subscriber</li>
	 * <li>if the given resource is a closed project (they are ineligible for synchronization)</li>
	 * <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 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
	 * @return status with code <code>OK</code> if there were no problems;
	 *     otherwise a description (possibly a multi-status) consisting of
	 *     low-severity warnings or informational messages. 
	 * @exception CoreException 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;
	
	/**
	 * Returns the list of available comparison criteria supported by this subscriber.
	 */
	abstract public ComparisonCriteria[] getComparisonCriterias();
	
	/**
	 * Returns the comparison criteria that will be used by the sync info created by
	 * this subscriber.
	 */
	abstract public ComparisonCriteria getCurrentComparisonCriteria();
	
	/**
	 * Set the current comparison criteria to the one defined by the given id. An exception is
	 * thrown if the id is not suported by this subscriber.
	 */
	abstract public void setCurrentComparisonCriteria(String id) throws TeamException;

	/**
	 * Answers <code>true</code> if the base tree is maintained by this subscriber. If the base
	 * tree is not considered than the subscriber can be considered as not supported three-way
	 * comparisons. Instead comparisons are made between the local and remote only without
	 * consideration for the base.
	 */
	abstract public boolean isThreeWay();
	
	/**
	 * 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(ITeamResourceChangeListener listener) {
		synchronized (listeners) {
			if(! listeners.contains(listener)) {
				listeners.add(listener);
			}
		}
	}

	/**
	 * Removes a listener previously registered with this team subscriber.
	 * Has no affect if an identical listener is not registered.
	 * 
	 * @param listener a team resource change listener
	 */	
	public void removeListener(ITeamResourceChangeListener listener) {
		synchronized (listeners) {
			listeners.remove(listener);
		}
	}
	
	/**
	 * 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 ISafeRunnable to ensure that
	 * client exceptions do not effect the notification to other clients.
	 */
	protected void fireTeamResourceChange(final TeamDelta[] deltas) {
		ITeamResourceChangeListener[] allListeners;
		// Copy the listener list so we're not calling client code while synchronized
		synchronized(listeners) {
			allListeners = (ITeamResourceChangeListener[]) listeners.toArray(new ITeamResourceChangeListener[listeners.size()]);
		}
		// Notify the listeners safely so all will receive notification
		for (int i = 0; i < allListeners.length; i++) {
			final ITeamResourceChangeListener listener = allListeners[i];
			Platform.run(new ISafeRunnable() {
				public void handleException(Throwable exception) {
					// don't log the exception....it is already being logged in Platform#run
	}
				public void run() throws Exception {
					listener.teamResourceChanged(deltas);

				}
			});
		}
	}

	/**
	 * Return an array of all out-of-sync resources (getKind() != 0) 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 out-of-sync descendants of a set of resources. 
	 * <p>
	 * A return value of an empty array indicates that there are no out-of-sync resources
	 * supervised by the subscriber. A return of <code>null</code> indicates that the
	 * subscriber does not support this operation in an optimized fashion. In this case,
	 * the caller can determine the out-of-sync resources by traversing the resource
	 * structure form the roots of the subscriber (@see <code>getRoots()</code>).</p>
	 * 
	 * @param resources
	 * @param depth
	 * @param monitor
	 * @return
	 */
	public SyncInfo[] getAllOutOfSync(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
		return null;
	}
	}
