/*******************************************************************************
 * Copyright (c) 2002 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 * IBM - Initial API and implementation
 ******************************************************************************/
package org.eclipse.team.internal.ccvs.core;
 
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.team.IMoveDeleteHook;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.Team;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.sync.IRemoteSyncElement;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.core.client.Commit;
import org.eclipse.team.internal.ccvs.core.client.Session;
import org.eclipse.team.internal.ccvs.core.client.Tag;
import org.eclipse.team.internal.ccvs.core.client.Update;
import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.client.listeners.AdminKSubstListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
import org.eclipse.team.internal.ccvs.core.streams.CRLFtoLFInputStream;
import org.eclipse.team.internal.ccvs.core.streams.LFtoCRLFInputStream;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;
import org.eclipse.team.internal.ccvs.core.util.PrepareForReplaceVisitor;
import org.eclipse.team.internal.ccvs.core.util.ReplaceWithBaseVisitor;

/**
 * This class acts as both the ITeamNature and the ITeamProvider instances
 * required by the Team core.
 * 
 * The current stat of this class and it's plugin is EXPERIMENTAL.
 * As such, it is subject to change except in it's conformance to the
 * TEAM API which it implements.
 * 
 * Questions:
 * 
 * How should a project/reource rename/move effect the provider?
 * 
 * Currently we always update with -P. Is this OK?
 *  - A way to allow customizable options would be nice
 * 
 * Is the -l option valid for commit and does it work properly for update and commit?
 * 
 * Do we need an IUserInteractionProvider in the CVS core
 * 	- prompt for user info (caching could be separate)
 * 	- get release comments
 * 	- prompt for overwrite of unmanaged files
 * 
 * Need a mechanism for communicating meta-information (provided by Team?)
 * 
 * Should pass null when there are no options for a cvs command
 * 
 * We currently write the files to disk and do a refreshLocal to
 * have them appear in Eclipse. This may be changed in the future.
 */
public class CVSTeamProvider extends RepositoryProvider {
	private static final boolean IS_CRLF_PLATFORM = Arrays.equals(
		System.getProperty("line.separator").getBytes(), new byte[] { '\r', '\n' }); //$NON-NLS-1$

	private CVSWorkspaceRoot workspaceRoot;
	private IProject project;
	private String comment = "";  //$NON-NLS-1$
	
	private static IMoveDeleteHook moveDeleteHook;
		
	/**
	 * No-arg Constructor for IProjectNature conformance
	 */
	public CVSTeamProvider() {
	}
	


	/**
	 * @see IProjectNature#deconfigure()
	 */
	public void deconfigure() throws CoreException {
		// when a nature is removed from the project, notify the synchronizer that
		// we no longer need the sync info cached. This does not affect the actual CVS
		// meta directories on disk, and will remain unless a client calls unmanage().
		try {
			EclipseSynchronizer.getInstance().flush(getProject(), true, true /*flush deep*/, null);
		} catch(CVSException e) {
			throw new CoreException(e.getStatus());
		} finally {
			CVSProviderPlugin.broadcastProjectDeconfigured(getProject());
		}
	}
	
	/**
	 * @see IProjectNature#getProject()
	 */
	public IProject getProject() {
		return project;
	}
	


	/**
	 * @see IProjectNature#setProject(IProject)
	 */
	public void setProject(IProject project) {
		this.project = project;
		try {
			this.workspaceRoot = new CVSWorkspaceRoot(project);
			// Ensure that the project has CVS info
			if (workspaceRoot.getLocalRoot().getFolderSyncInfo() == null) {
				throw new CVSException(new CVSStatus(CVSStatus.ERROR, Policy.bind("CVSTeamProvider.noFolderInfo", project.getName()))); //$NON-NLS-1$
			}
		} catch (CVSException e) {
			// Log any problems creating the CVS managed resource
			CVSProviderPlugin.log(e);
		}
	}



	/**
	 * Add the given resources to the project. 
	 * <p>
	 * The sematics follow that of CVS in the sense that any folders 
	 * being added are created remotely as a result of this operation 
	 * while files are created remotely on the next commit. 
	 * </p>
	 * <p>
	 * This method uses the team file type registry to determine the type
	 * of added files. If the extension of the file is not in the registry,
	 * the file is assumed to be binary.
	 * </p>
	 * <p>
	 * NOTE: for now we do three operations: one each for folders, text files and binary files.
	 * We should optimize this when time permits to either use one operations or defer server
	 * contact until the next commit.
	 * </p>
	 * 
	 * <p>
	 * There are special semantics for adding the project itself to the repo. In this case, the project 
	 * must be included in the resources array.
	 * </p>
	 */
	public void add(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {	
		
		// Visit the children of the resources using the depth in order to
		// determine which folders, text files and binary files need to be added
		// A TreeSet is needed for the folders so they are in the right order (i.e. parents created before children)
		final SortedSet folders = new TreeSet();
		// Sets are required for the files to ensure that files will not appear twice if there parent was added as well
		// and the depth isn't zero
		final Map /* from KSubstOption to Set */ files = new HashMap();
		final TeamException[] eHolder = new TeamException[1];
		for (int i=0; i<resources.length; i++) {
			
			final IResource currentResource = resources[i];
			
			// Throw an exception if the resource is not a child of the receiver
			checkIsChild(currentResource);
			
			try {		
				// Auto-add parents if they are not already managed
				IContainer parent = currentResource.getParent();
				ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(currentResource);
				while (parent.getType() != IResource.ROOT && parent.getType() != IResource.PROJECT && ! cvsResource.isManaged()) {
					folders.add(parent.getProjectRelativePath().toString());
					parent = parent.getParent();
				}
					
				// Auto-add children
				currentResource.accept(new IResourceVisitor() {
					public boolean visit(IResource resource) {
						ICVSResource mResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
						// Add the resource is its not already managed and it was either
						// added explicitly (is equal currentResource) or is not ignored
						if (! mResource.isManaged() && (currentResource.equals(resource) || ! mResource.isIgnored())) {
							String name = resource.getProjectRelativePath().toString();
							if (resource.getType() == IResource.FILE) {
								KSubstOption ksubst = KSubstOption.fromFile((IFile) resource);
								Set set = (Set) files.get(ksubst);
								if (set == null) {
									set = new HashSet();
									files.put(ksubst, set);
								}
								set.add(name);
							} else {
								folders.add(name);
							}
						}
						// Always return true and let the depth determine if children are visited
						return true;
					}
				}, depth, false);
			} catch (CoreException e) {
				throw new CVSException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, Policy.bind("CVSTeamProvider.visitError", new Object[] {resources[i].getFullPath()}), e)); //$NON-NLS-1$
			}
		}
		// If an exception occured during the visit, throw it here
		if (eHolder[0] != null)
			throw eHolder[0];
	
		// XXX Do we need to add the project 
		
		// Add the folders, followed by files!
		IStatus status;
		Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
		progress.beginTask(null, 10 + files.size() * 10 + (folders.isEmpty() ? 0 : 10));
		try {
			// Opening the session takes 10 units of time
			s.open(Policy.subMonitorFor(progress, 10));
			if (!folders.isEmpty()) {
				status = Command.ADD.execute(s,
					Command.NO_GLOBAL_OPTIONS,
					Command.NO_LOCAL_OPTIONS,
					(String[])folders.toArray(new String[folders.size()]),
					null,
					Policy.subMonitorFor(progress, 10));
				if (status.getCode() == CVSStatus.SERVER_ERROR) {
					throw new CVSServerException(status);
				}
			}
			for (Iterator it = files.entrySet().iterator(); it.hasNext();) {
				Map.Entry entry = (Map.Entry) it.next();
				KSubstOption ksubst = (KSubstOption) entry.getKey();
				Set set = (Set) entry.getValue();
				status = Command.ADD.execute(s,
					Command.NO_GLOBAL_OPTIONS,
					new LocalOption[] { ksubst },
					(String[])set.toArray(new String[set.size()]),
					null,
					Policy.subMonitorFor(progress, 10));
				if (status.getCode() == CVSStatus.SERVER_ERROR) {
					throw new CVSServerException(status);
				}
			}
		} finally {
			s.close();
			progress.done();
		}
	}
	
	/**
	 * Checkin any local changes using "cvs commit ...".
	 * 
	 * @see ITeamProvider#checkin(IResource[], int, IProgressMonitor)
	 */
	public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
			
		// Build the local options
		List localOptions = new ArrayList();
		localOptions.add(Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment));

		// If the depth is not infinite, we want the -l option
		if (depth != IResource.DEPTH_INFINITE) {
			localOptions.add(Commit.DO_NOT_RECURSE);
		}
		LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);

		// Build the arguments list
		String[] arguments = getValidArguments(resources, commandOptions);
					
		// Commit the resources
		IStatus status;
		Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
		progress.beginTask(null, 100);
		try {
			// Opening the session takes 20% of the time
			s.open(Policy.subMonitorFor(progress, 20));
			status = Command.COMMIT.execute(s,
			Command.NO_GLOBAL_OPTIONS,
			commandOptions,
			arguments, null,
			Policy.subMonitorFor(progress, 80));
		} finally {
			s.close();
			progress.done();
		}
		if (status.getCode() == CVSStatus.SERVER_ERROR) {
			throw new CVSServerException(status);
		}
	}

	/**
	 * Checkout the provided resources so they can be modified locally and committed.
	 * 
	 * Currently, we support only the optimistic model so checkout does nothing.
	 * 
	 * @see ITeamProvider#checkout(IResource[], int, IProgressMonitor)
	 */
	public void checkout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
	}
		
	/**
	 * @see ITeamProvider#delete(IResource[], int, IProgressMonitor)
	 */
	public void delete(IResource[] resources, final IProgressMonitor progress) throws TeamException {
		try {
			progress.beginTask(null, 100);
			
			// Delete any files locally and record the names.
			// Use a resource visitor to ensure the proper depth is obtained
			final IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(progress, 30);
			subProgress.beginTask(null, 256);
			final List files = new ArrayList(resources.length);
			final TeamException[] eHolder = new TeamException[1];
			for (int i=0;i<resources.length;i++) {
				IResource resource = resources[i];
				checkIsChild(resource);
				try {
					if (resource.exists()) {
						resource.accept(new IResourceVisitor() {
							public boolean visit(IResource resource) {
								try {
									ICVSResource cvsResource = workspaceRoot.getCVSResourceFor(resource);
									if (cvsResource.isManaged()) {
										String name = resource.getProjectRelativePath().toString();
										if (resource.getType() == IResource.FILE) {
											files.add(name);
											((IFile)resource).delete(false, true, subProgress);
										}
									}
								} catch (CoreException e) {
									eHolder[0] = wrapException(e);
									// If there was a problem, don't visit the children
									return false;
								}
								// Always return true and let the depth determine if children are visited
								return true;
							}
						}, IResource.DEPTH_INFINITE, false);
					} else if (resource.getType() == IResource.FILE) {
						// If the resource doesn't exist but is a file, queue it for removal
						files.add(resource.getProjectRelativePath().toString());
					}
				} catch (CoreException e) {
					throw wrapException(e);
				}
			}
			subProgress.done();
			// If an exception occured during the visit, throw it here
			if (eHolder[0] != null) throw eHolder[0];		
			// If there are no files to delete, we are done
			if (files.isEmpty()) return;
			
			// Remove the files remotely
			IStatus status;
			Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
			s.open(progress);
			try {
				status = Command.REMOVE.execute(s,
				Command.NO_GLOBAL_OPTIONS,
				Command.NO_LOCAL_OPTIONS,
				(String[])files.toArray(new String[files.size()]),
				null,
				Policy.subMonitorFor(progress, 70));
			} finally {
				s.close();
			}
			if (status.getCode() == CVSStatus.SERVER_ERROR) {
				throw new CVSServerException(status);
			}	
		} finally {
			progress.done();
		}
	}
	
	/** 
	 * Diff the resources against the repository and write the output to the provided 
	 * PrintStream in a form that is usable as a patch. The patch is rooted at the
	 * project.
	 */
	public void diff(IResource resource, LocalOption[] options, PrintStream stream,
		IProgressMonitor progress) throws TeamException {
		
		// Determine the command root and arguments arguments list
		ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
		ICVSFolder commandRoot;
		String[] arguments;
		if (cvsResource.isFolder()) {
			commandRoot = (ICVSFolder)cvsResource;
			arguments = new String[] {Session.CURRENT_LOCAL_FOLDER};
		} else {
			commandRoot = cvsResource.getParent();
			arguments = new String[] {cvsResource.getName()};
		}

		Session s = new Session(workspaceRoot.getRemoteLocation(), commandRoot);
		progress.beginTask(null, 100);
		try {
			s.open(Policy.subMonitorFor(progress, 20));
			Command.DIFF.execute(s,
				Command.NO_GLOBAL_OPTIONS,
				options,
				arguments,
				new DiffListener(stream),
				Policy.subMonitorFor(progress, 80));
		} finally {
			s.close();
			progress.done();
		}
	}
	
	/**
	 * Replace the local version of the provided resources with the remote using "cvs update -C ..."
	 * 
	 * @see ITeamProvider#get(IResource[], int, IProgressMonitor)
	 */
	public void get(IResource[] resources, final int depth, IProgressMonitor progress) throws TeamException {
		get(resources, depth, null, progress);
	}
	
	public void get(final IResource[] resources, final int depth, CVSTag tag, IProgressMonitor progress) throws TeamException {
		try {
			progress.beginTask(null, 100);
			
			// Handle the retrival of the base in a special way
			if (tag != null && tag.equals(CVSTag.BASE)) {
				new ReplaceWithBaseVisitor().replaceWithBase(getProject(), resources, depth, Policy.subMonitorFor(progress, 100)); //$NON-NLS-1$
				return;
			}
			
			// Prepare for the replace (special handling for "cvs added" and "cvs removed" resources
			new PrepareForReplaceVisitor().visitResources(getProject(), resources, "CVSTeamProvider.scrubbingResource", depth, Policy.subMonitorFor(progress, 30)); //$NON-NLS-1$
						
			// Perform an update, ignoring any local file modifications
			List options = new ArrayList();
			options.add(Update.IGNORE_LOCAL_CHANGES);
			if(depth != IResource.DEPTH_INFINITE) {
				options.add(Command.DO_NOT_RECURSE);
			}
			LocalOption[] commandOptions = (LocalOption[]) options.toArray(new LocalOption[options.size()]);
			update(resources, commandOptions, tag, true /*createBackups*/, Policy.subMonitorFor(progress, 70));
		} finally {
			progress.done();
		}
	}
	
	/**
	 * Return the remote location to which the receiver's project is mapped.
	 */
	public ICVSRepositoryLocation getRemoteLocation() throws CVSException {
		try {
			return workspaceRoot.getRemoteLocation();
		} catch (CVSException e) {
			// If we can't get the remote location, we should disconnect since nothing can be done with the provider
			try {
				Team.removeNatureFromProject(project, CVSProviderPlugin.getTypeId(), Policy.monitorFor(null));
			} catch (TeamException ex) {
				CVSProviderPlugin.log(ex);
			}
			// We need to trigger a decorator refresh					
			throw e;
		}
	}
	
	/**
	 * @see ITeamProvider#hasRemote(IResource)
	 * XXX to be removed when sync methods are removed from ITeamProvider
	 */
	public boolean hasRemote(IResource resource) {
		try {
			ICVSResource cvsResource = workspaceRoot.getCVSResourceFor(resource);
			int type = resource.getType();
			if(type!=IResource.FILE) {
				if(type==IResource.PROJECT) {
					return ((ICVSFolder)cvsResource).isCVSFolder();
				} else {
					return cvsResource.isManaged();
				}
			} else {
				ResourceSyncInfo info = cvsResource.getSyncInfo();
				if(info!=null) {
					return !info.isAdded();
				} else {
					return false;
				}
			}					
		} catch(CVSException e) {
			return false;
		}
	}
	
	/**
	 * @see ITeamProvider#isLocallyCheckedOut(IResource)
 	 * XXX to be removed when sync methods are removed from ITeamProvider
	 */
	public boolean isCheckedOut(IResource resource) {
		ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
		return cvsResource.isManaged();
	}
	
	/*
	 * Use specialiazed tagging to move all local changes (including additions and
	 * deletions) to the specified branch.
	 */
	public void makeBranch(IResource[] resources, CVSTag versionTag, CVSTag branchTag, boolean moveToBranch, boolean eclipseWay, IProgressMonitor monitor) throws TeamException {
		
		// Determine the total amount of work
		int totalWork = 10 + (versionTag!= null ? 60 : 40) + (moveToBranch ? 20 : 0);
		monitor.beginTask(Policy.bind("CVSTeamProvider.makeBranch"), totalWork);  //$NON-NLS-1$
		try {
			
			// Determine which tag command to used depending on whether the Eclipse specific
			// method of branching is requested
			Tag tagCommand = Command.TAG;
			if (eclipseWay) {
				tagCommand = Command.CUSTOM_TAG;
			}
			
			// Build the arguments list
			String[] arguments = getValidArguments(resources, Command.NO_LOCAL_OPTIONS);
			
			// Tag the remote resources
			Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
			try {
				s.open(Policy.subMonitorFor(monitor, 10));
				
				IStatus status;
				if (versionTag != null) {
					// Version using tag and braqnch using rtag
					status = tagCommand.execute(s,
						Command.NO_GLOBAL_OPTIONS,
						Command.NO_LOCAL_OPTIONS,
						versionTag,
						arguments,
						null,
						Policy.subMonitorFor(monitor, 40));
					if (status.getCode() != CVSStatus.SERVER_ERROR) {
						// XXX Could use RTAG here when it works
						status = tagCommand.execute(s,
							Command.NO_GLOBAL_OPTIONS,
							Command.NO_LOCAL_OPTIONS,
							branchTag,
							arguments,
							null,
							Policy.subMonitorFor(monitor, 20));
					}
				} else {
					// Just branch using tag
					status = tagCommand.execute(s,
						Command.NO_GLOBAL_OPTIONS,
						Command.NO_LOCAL_OPTIONS,
						branchTag,
						arguments,
						null,
						Policy.subMonitorFor(monitor, 40));
	
				}
				if (status.getCode() == CVSStatus.SERVER_ERROR) {
					throw new CVSServerException(status);
				}
			} finally {
				s.close();
			}
			
			// Set the tag of the local resources to the branch tag (The update command will not
			// properly update "cvs added" and "cvs removed" resources so a custom visitor is used
			if (moveToBranch) {
				if (eclipseWay) {
					setTag(resources, branchTag, Policy.subMonitorFor(monitor, 20));
				} else {
					update(resources, Command.NO_LOCAL_OPTIONS, branchTag, true /*createBackups*/, Policy.subMonitorFor(monitor, 20));
				}
			}
		} finally {
			monitor.done();
		}
	}
	
	/**
	 * Update the sync info of the local resource associated with the sync element such that
	 * the revision of the local resource matches that of the remote resource.
	 * This will allow commits on the local resource to succeed.
	 * 
	 * Only file resources can be merged.
	 */
	public void merged(IRemoteSyncElement[] elements) throws TeamException {	
		for (int i=0;i<elements.length;i++) {
			((CVSRemoteSyncElement)elements[i]).makeOutgoing(Policy.monitorFor(null));
		}
	}
	
	/**
	 * @see ITeamProvider#move(IResource, IPath, IProgressMonitor)
	 */
	public void moved(IPath source, IResource resource, IProgressMonitor progress) throws TeamException {
	}

	/**
	 * Set the comment to be used on the next checkin
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}
		
	/**
	 * Set the connection method for the given resource's
	 * project. If the conection method name is invalid (i.e.
	 * no corresponding registered connection method), false is returned.
	 */
	public boolean setConnectionInfo(IResource resource, String methodName, IUserInfo userInfo, IProgressMonitor monitor) throws TeamException {
		checkIsChild(resource);
		try {
			monitor.beginTask(Policy.bind("CVSTeamProvider.connectionInfo", project.getName()), 100); //$NON-NLS-1$
			
			if (!CVSRepositoryLocation.validateConnectionMethod(methodName))
				return false;
				
			// Get the original location
			ICVSRepositoryLocation location = workspaceRoot.getRemoteLocation();
			
			// Make a copy to work on
			CVSRepositoryLocation newLocation = CVSRepositoryLocation.fromString(location.getLocation());
			newLocation.setMethod(methodName);
			newLocation.setUserInfo(userInfo);
	
			// Validate that a connection can be made with the new location
			try {
				newLocation.validateConnection(Policy.subMonitorFor(monitor, 20));
			} catch (CVSException e) {
				// XXX We should really only do this if it didn't exist previously
				CVSProviderPlugin.getProvider().disposeRepository(newLocation);
				throw e;
			}
			
			// Add the location to the provider
			CVSProvider.getInstance().addRepository(newLocation);
			
			// Set the project to use the new Locations
			setRemoteRoot(newLocation, Policy.subMonitorFor(monitor, 80));
			return true;
		} finally {
			monitor.done();
		}
	}
	
	/*
	 * This method sets the tag for a project.
	 * It expects to be passed an InfiniteSubProgressMonitor
	 */
	private void setTag(final IResource[] resources, final CVSTag tag, IProgressMonitor monitor) throws TeamException {
	
		workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
			public void run(IProgressMonitor progress) throws CVSException {
				try {
					// 512 ticks gives us a maximum of 2048 which seems reasonable for folders and files in a project
					progress.beginTask(null, 100);
					final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100);
					monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", project.getName()), 512);  //$NON-NLS-1$
					
					// Visit all the children folders in order to set the root in the folder sync info
					for (int i = 0; i < resources.length; i++) {
						CVSWorkspaceRoot.getCVSResourceFor(resources[i]).accept(new ICVSResourceVisitor() {
							public void visitFile(ICVSFile file) throws CVSException {
								monitor.worked(1);
								ResourceSyncInfo info = file.getSyncInfo();
								if (info != null) {
									monitor.subTask(Policy.bind("CVSTeamProvider.updatingFile", info.getName())); //$NON-NLS-1$
									MutableResourceSyncInfo newInfo = info.cloneMutable();
									newInfo.setTag(tag);
									file.setSyncInfo(newInfo);
								}
							};
							public void visitFolder(ICVSFolder folder) throws CVSException {
								monitor.worked(1);
								FolderSyncInfo info = folder.getFolderSyncInfo();
								if (info != null) {
									monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$
									folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, info.getIsStatic()));
									folder.acceptChildren(this);
								}
							};
						});
					}
				} finally {
					progress.done();
				}
			}
		}, monitor);
	}
	
	/** 
	 * Tag the resources in the CVS repository with the given tag.
	 * 
	 * The returned IStatus will be a status containing any errors or warnings.
	 * If the returned IStatus is a multi-status, the code indicates the severity.
	 * Possible codes are:
	 *    CVSStatus.OK - Nothing to report
	 *    CVSStatus.SERVER_ERROR - The server reported an error
	 *    any other code - warning messages received from the server
	 */
	public IStatus tag(IResource[] resources, int depth, CVSTag tag, IProgressMonitor progress) {
						
		// Build the local options
		List localOptions = new ArrayList();
		// If the depth is not infinite, we want the -l option
		if (depth != IResource.DEPTH_INFINITE)
			localOptions.add(Tag.DO_NOT_RECURSE);
		LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
				
		IStatus status;
		try {
			// Build the arguments list
			String[] arguments = getValidArguments(resources, commandOptions);

			Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
			progress.beginTask(null, 100);
			try {
				// Opening the session takes 20% of the time
				s.open(Policy.subMonitorFor(progress, 20));
				status = Command.TAG.execute(s,
					Command.NO_GLOBAL_OPTIONS,
					commandOptions,
					tag,
					arguments,
					null,
					Policy.subMonitorFor(progress, 80));
			} finally {
				s.close();
				progress.done();
			}
		} catch(CVSException e) {
			status = e.getStatus();
		}
		return status;
	}
	
	/**
	 * Currently, we support only the optimistic model so uncheckout dores nothing.
	 * 
	 * @see ITeamProvider#uncheckout(IResource[], int, IProgressMonitor)
	 */
	public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
	}
	
	/**
	 * Generally useful update.
	 * 
	 * The tag parameter determines any stickyness after the update is run. If tag is null, any tagging on the
	 * resources being updated remain the same. If the tag is a branch, version or date tag, then the resources
	 * will be appropriatly tagged. If the tag is HEAD, then there will be no tag on the resources (same as -A
	 * clear sticky option).
	 * 
	 * @param createBackups if true, creates .# files for updated files
	 */
	public void update(IResource[] resources, LocalOption[] options, CVSTag tag, boolean createBackups, IProgressMonitor progress) throws TeamException {
		// Build the local options
		List localOptions = new ArrayList();
		
		// Use the appropriate tag options
		if (tag != null) {
			localOptions.add(Update.makeTagOption(tag));
		}
		
		// Build the arguments list
		localOptions.addAll(Arrays.asList(options));
		LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
		String[] arguments = getValidArguments(resources, commandOptions);

		IStatus status;
		Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
		progress.beginTask(null, 100);
		try {
			// Opening the session takes 20% of the time
			s.open(Policy.subMonitorFor(progress, 20));
			status = Command.UPDATE.execute(s, Command.NO_GLOBAL_OPTIONS, commandOptions, arguments,
				null, Policy.subMonitorFor(progress, 80), createBackups);
		} finally {
			progress.done();
			s.close();
		}
		if (status.getCode() == CVSStatus.SERVER_ERROR) {
			// XXX diff errors??
			throw new CVSServerException(status);
		}
	}
		
	public static String getMessageFor(Exception e) {
		String message = Policy.bind(e.getClass().getName(), new Object[] {e.getMessage()});
		if (message.equals(e.getClass().getName()))
			message = Policy.bind("CVSTeamProvider.exception", new Object[] {e.toString()}); //$NON-NLS-1$
		return message;
	}
	
	
	/*
	 * @see ITeamProvider#refreshState(IResource[], int, IProgressMonitor)
	 */
	public void refreshState(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
		Assert.isTrue(false);
	}
	/*
	 * @see ITeamProvider#isOutOfDate(IResource)
	 * XXX to be removed when sync methods are removed from ITeamProvider
	 */
	public boolean isOutOfDate(IResource resource) {
		Assert.isTrue(false);
		return false;
	}
	
	/*
	 * @see ITeamProvider#isDirty(IResource)
	 */
	public boolean isDirty(IResource resource) {
		Assert.isTrue(false);
		return false;
	}
	
	public CVSWorkspaceRoot getCVSWorkspaceRoot() {
		return workspaceRoot;
	}
	
	/*
	 * Generate an exception if the resource is not a child of the project
	 */
	 private void checkIsChild(IResource resource) throws CVSException {
	 	if (!isChildResource(resource))
	 		throw new CVSException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, 
	 			Policy.bind("CVSTeamProvider.invalidResource", //$NON-NLS-1$
	 				new Object[] {resource.getFullPath().toString(), project.getName()}), 
	 			null));
	 }
	 
	/*
	 * Get the arguments to be passed to a commit or update
	 */
	private String[] getValidArguments(IResource[] resources, LocalOption[] options) throws CVSException {
		List arguments = new ArrayList(resources.length);
		for (int i=0;i<resources.length;i++) {
			checkIsChild(resources[i]);
			IPath cvsPath = resources[i].getFullPath().removeFirstSegments(1);
			if (cvsPath.segmentCount() == 0) {
				arguments.add(Session.CURRENT_LOCAL_FOLDER);
			} else {
				arguments.add(cvsPath.toString());
			}
		}
		return (String[])arguments.toArray(new String[arguments.size()]);
	}
	
	/*
	 * This method expects to be passed an InfiniteSubProgressMonitor
	 */
	public void setRemoteRoot(ICVSRepositoryLocation location, IProgressMonitor monitor) throws TeamException {

		// Check if there is a differnece between the new and old roots	
		final String root = location.getLocation();
		if (root.equals(workspaceRoot.getRemoteLocation())) 
			return;
	
		try {
			workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
				public void run(IProgressMonitor progress) throws CVSException {
					try {
						// 256 ticks gives us a maximum of 1024 which seems reasonable for folders is a project
						progress.beginTask(null, 100);
						final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100);
						monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", project.getName()), 256);  //$NON-NLS-1$
		
						// Visit all the children folders in order to set the root in the folder sync info
						workspaceRoot.getLocalRoot().accept(new ICVSResourceVisitor() {
							public void visitFile(ICVSFile file) throws CVSException {};
							public void visitFolder(ICVSFolder folder) throws CVSException {
								monitor.worked(1);
								FolderSyncInfo info = folder.getFolderSyncInfo();
								if (info != null) {
									monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$
									folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), root, info.getTag(), info.getIsStatic()));
									folder.acceptChildren(this);
								}
							};
						});
					} finally {
						progress.done();
					}
				}
			}, monitor);
		} finally {
			monitor.done();
		}
	}
	
	/*
	 * Helper to indicate if the resource is a child of the receiver's project
	 */
	private boolean isChildResource(IResource resource) {
		return resource.getProject().getName().equals(project.getName());
	}
	
	private static TeamException wrapException(CoreException e) {
		return new TeamException(statusFor(e));
	}
	
	private static IStatus statusFor(CoreException e) {
		// We should be taking out any status from the CVSException
		// and creating an array of IStatus!
		return new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, getMessageFor(e), e);
	}
	
	public void configureProject() throws CoreException {
		CVSProviderPlugin.broadcastProjectConfigured(getProject());
	}
	/**
	 * Sets the keyword substitution mode for the specified resources.
	 * <p>
	 * Applies the following rules in order:<br>
	 * <ul>
	 *   <li>If a file is not managed, skips it.</li>
	 *   <li>If a file is not changing modes, skips it.</li>
	 *   <li>If a file is being changed from binary to text, corrects line delimiters
	 *       then commits it, then admins it.</li>
	 *   <li>If a file is added, changes the resource sync information locally.</li>
	 *   <li>Otherwise commits the file (with FORCE to create a new revision), then admins it.</li>
	 * </ul>
	 * All files that are admin'd are committed with FORCE to prevent other developers from
	 * casually trying to commit pending changes to the repository without first checking out
	 * a new copy.  This is not a perfect solution, as they could just as easily do an UPDATE
	 * and not obtain the new keyword sync info.
	 * </p>
	 * 
	 * @param changeSet a map from IFile to KSubstOption
	 * @param monitor the progress monitor
	 * @return a status code indicating success or failure of the operation
	 * 
	 * @throws TeamException
	 */
	public IStatus setKeywordSubstitution(final Map /* from IFile to KSubstOption */ changeSet,
		IProgressMonitor monitor) throws TeamException {
		final IStatus[] result = new IStatus[] { ICommandOutputListener.OK };
		workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
			public void run(final IProgressMonitor monitor) throws CVSException {
				final Map /* from KSubstOption to List of String */ filesToAdmin = new HashMap();
				final List /* of String */ filesToCommit = new ArrayList();
				final Collection /* of ICVSFile */ filesToCommitAsText = new HashSet(); // need fast lookup
		
				/*** determine the resources to be committed and/or admin'd ***/
				for (Iterator it = changeSet.entrySet().iterator(); it.hasNext();) {
					Map.Entry entry = (Map.Entry) it.next();
					IFile file = (IFile) entry.getKey();
					KSubstOption toKSubst = (KSubstOption) entry.getValue();

					// only set keyword substitution if resource is a managed file
					checkIsChild(file);
					ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor(file);
					if (! mFile.isManaged()) continue;
					
					// only set keyword substitution if new differs from actual
					ResourceSyncInfo info = mFile.getSyncInfo();
					KSubstOption fromKSubst = info.getKeywordMode();
					if (toKSubst.equals(fromKSubst)) continue;
					
					// change resource sync info immediately for an outgoing addition
					if (info.isAdded()) {
						MutableResourceSyncInfo newInfo = info.cloneMutable();
						newInfo.setKeywordMode(toKSubst);
						mFile.setSyncInfo(newInfo);
						continue;
					}

					// nothing do to for deletions
					if (info.isDeleted()) continue;

					// file exists remotely so we'll have to commit it
					String remotePath = mFile.getRelativePath(workspaceRoot.getLocalRoot());
					if (fromKSubst.isBinary() && ! toKSubst.isBinary()) {
						// converting from binary to text
						cleanLineDelimiters(file, IS_CRLF_PLATFORM, new NullProgressMonitor()); // XXX need better progress monitoring
						// remember to commit the cleaned resource as text before admin
						filesToCommitAsText.add(mFile);
					}
					// force a commit to bump the revision number
					makeDirty(file);
					filesToCommit.add(remotePath);
					// remember to admin the resource
					List list = (List) filesToAdmin.get(toKSubst);
					if (list == null) {
						list = new ArrayList();
						filesToAdmin.put(toKSubst, list);
					}
					list.add(remotePath);
				}
			
				/*** commit then admin the resources ***/
				// compute the total work to be performed
				int totalWork = filesToCommit.size();
				for (Iterator it = filesToAdmin.values().iterator(); it.hasNext();) {
					List list = (List) it.next();
					totalWork += list.size();
				}
				if (totalWork != 0) {
					Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
					monitor.beginTask(Policy.bind("CVSTeamProvider.settingKSubst"), 5 + totalWork); //$NON-NLS-1$
					try {
						s.open(Policy.subMonitorFor(monitor, 5));
						
						// commit files that changed from binary to text
						// NOTE: The files are committed as text with conversions even if the
						//       resource sync info still says "binary".
						if (filesToCommit.size() != 0) {
							s.setTextTransferOverride(filesToCommitAsText);
							result[0] = Command.COMMIT.execute(s, Command.NO_GLOBAL_OPTIONS,
								new LocalOption[] { Commit.DO_NOT_RECURSE, Commit.FORCE,
									Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment) },
								(String[]) filesToCommit.toArray(new String[filesToCommit.size()]),
								null, Policy.subMonitorFor(monitor, filesToCommit.size()));
							s.setTextTransferOverride(null);
							// if errors were encountered, abort
							if (! result[0].isOK()) return;
						}
						
						// admin files that changed keyword substitution mode
						// NOTE: As confirmation of the completion of a command, the server replies
						//       with the RCS command output if a change took place.  Rather than
						//       assume that the command succeeded, we listen for these lines
						//       and update the local ResourceSyncInfo for the particular files that
						//       were actually changed remotely.
						for (Iterator it = filesToAdmin.entrySet().iterator(); it.hasNext();) {
							Map.Entry entry = (Map.Entry) it.next();
							KSubstOption toKSubst = (KSubstOption) entry.getKey();
							List list = (List) entry.getValue();
							// do it
							result[0] = Command.ADMIN.execute(s, Command.NO_GLOBAL_OPTIONS,
								new LocalOption[] { toKSubst },
								(String[]) list.toArray(new String[list.size()]),
								new AdminKSubstListener(toKSubst),
								Policy.subMonitorFor(monitor, list.size()));
							// if errors were encountered, abort
							if (! result[0].isOK()) return;
						}
					} finally {
						s.close();
						monitor.done();
					}
				}
			}
		}, Policy.monitorFor(monitor));
		return result[0];
	}
	
	/**
	 * Fixes the line delimiters in the local file to reflect the platform's
	 * native encoding.  Performs CR/LF -> LF or LF -> CR/LF conversion
	 * depending on the platform but does not affect delimiters that are
	 * already correctly encoded.
	 */
	public static void cleanLineDelimiters(IFile file, boolean useCRLF, IProgressMonitor progress)
		throws CVSException {
		try {
			// convert delimiters in memory
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			InputStream is = new BufferedInputStream(file.getContents());
			try {
				is = new CRLFtoLFInputStream(is);
				if (useCRLF) is = new LFtoCRLFInputStream(is);
				for (int b; (b = is.read()) != -1;) bos.write(b);
				bos.close();
			} finally {
				is.close();
			}
			// write file back to disk with corrected delimiters if changes were made
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			file.setContents(bis, false /*force*/, false /*keepHistory*/, progress);
		} catch (CoreException e) {
			throw CVSException.wrapException(file, Policy.bind("CVSTeamProvider.cleanLineDelimitersException"), e); //$NON-NLS-1$
		} catch (IOException e) {
			throw CVSException.wrapException(file, Policy.bind("CVSTeamProvider.cleanLineDelimitersException"), e); //$NON-NLS-1$
		}
	}
	
	/*
	 * Marks a file as dirty.
	 */
	private static void makeDirty(IFile file) throws CVSException {
		ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor(file);
		mFile.setTimeStamp(null /*set the timestamp to current time*/);
	}
	
	/*
	 * @see RepositoryProvider#getID()
	 */
	public String getID() {
		return CVSProviderPlugin.getTypeId();
	}
	
	/*
	 * @see RepositoryProvider#getMoveDeleteHook()
	 */
	public IMoveDeleteHook getMoveDeleteHook() {
		return moveDeleteHook;
	}
	
	/*
	 * Return the currently registered Move/Delete Hook
	 */
	public static IMoveDeleteHook getRegisteredMoveDeleteHook() {
		return moveDeleteHook;
	}
	
	/*
	 * Set the Move/Delete hook of the CVS Team Provider. This is for internal use by CVS only. 
	 * It is not to be used by other clients
	 */
	 public static void setMoveDeleteHook(IMoveDeleteHook hook) {
	 	moveDeleteHook = hook;
	 }
}