/*******************************************************************************
 * Copyright (c) 2000, 2006 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.ccvs.core.syncinfo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.variants.*;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.resources.*;

/**
 * CVS Specific refresh operation
 */
public class CVSResourceVariantTree extends ResourceVariantTree {

	private CVSTag tag;
	private boolean cacheFileContentsHint;
	private CVSSyncTreeSubscriber subscriber;

	public CVSResourceVariantTree(ResourceVariantByteStore cache, CVSTag tag, boolean cacheFileContentsHint) {
		super(cache);
		this.tag = tag;
		this.cacheFileContentsHint = cacheFileContentsHint;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache()
	 */
	public ResourceVariantByteStore getByteStore() {
		return super.getByteStore();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource)
	 */
	protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException {
		if (remote != null) {
			return super.getBytes(local, remote);
		} else {
			if (local.getType() == IResource.FOLDER) {
				// If there is no remote, use the local sync for the folder
				return getBaseBytes((IContainer)local, getTag(local));
			}
			return null;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteChildren(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IResourceVariant[] fetchMembers(IResourceVariant remote, IProgressMonitor progress) throws TeamException {
		ICVSRemoteResource[] children = remote != null ? (ICVSRemoteResource[])((RemoteResource)remote).members(progress) : new ICVSRemoteResource[0];
		IResourceVariant[] result = new IResourceVariant[children.length];
		for (int i = 0; i < children.length; i++) {
			result[i] = (IResourceVariant)children[i];
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.subscribers.RefreshOperation#buildRemoteTree(org.eclipse.core.resources.IResource, int, boolean, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
		return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, getTag(resource), isCacheFileContentsHint(), depth, monitor);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefreshOperation#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor)
	 */
	public IResource[] collectChanges(IResource local,
			IResourceVariant remote, int depth, IProgressMonitor monitor)
			throws TeamException {
		return super.collectChanges(local, remote, depth, monitor);
	}

	public IResource[] members(IResource resource) throws TeamException {
		if (resource.getType() == IResource.FILE) {
			return new IResource[0];
		}
		// Must ensure that any shared folders are included
		Set members = new HashSet();
		members.addAll(Arrays.asList(super.members(resource)));
		try {
			IResource[]  localMembers = ((IContainer)resource).members(true);
			for (int i = 0; i < localMembers.length; i++) {
				IResource local = localMembers[i];
				if (local.getType() != IResource.FILE) {
					ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local);
					if (folder.isCVSFolder()) {
						members.add(local);
					}
				}
			}
		} catch (CoreException e) {
			throw CVSException.wrapException(e);
		}
		return (IResource[]) members.toArray(new IResource[members.size()]);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#roots()
	 */
	public IResource[] roots() {
		return subscriber.roots();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource)
	 */
	public IResourceVariant getResourceVariant(IResource resource) throws TeamException {
		byte[] remoteBytes = getByteStore().getBytes(resource);
		if (remoteBytes == null) {
			// There is no remote handle for this resource
			return null;
		} else {
			if (resource.getType() == IResource.FILE) {
				byte[] parentBytes = getParentBytes(resource);
				if (parentBytes == null) {
					IProject project = resource.getProject();
					if (project.exists() && RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()) != null) {
						CVSProviderPlugin.log(new CVSException( 
								NLS.bind(CVSMessages.ResourceSynchronizer_missingParentBytesOnGet, new String[] { getSyncName(getByteStore()).toString(), resource.getFullPath().toString() }))); 
						// Assume there is no remote and the problem is a programming error
					}
					return null;
				}
				return RemoteFile.fromBytes(resource, remoteBytes, parentBytes);
			} else {
				return RemoteFolder.fromBytes(resource, remoteBytes);
			}
		}
	}

	private String getSyncName(ResourceVariantByteStore cache) {
		if (cache instanceof PersistantResourceVariantByteStore) {
			return ((PersistantResourceVariantByteStore)cache).getSyncName().toString();
		}
		return cache.getClass().getName();
	}
	
	
	private byte[] getParentBytes(IResource resource) throws TeamException {
		IContainer parent = resource.getParent();
		byte[] bytes =  getByteStore().getBytes(parent);
		if (bytes == null ) {
			bytes = getBaseBytes(parent, getTag(resource));
		}
		return bytes;
	}

	private byte[] getBaseBytes(IContainer parent, CVSTag tag) throws CVSException {
		byte[] bytes;
		// Look locally for the folder bytes
		ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(parent);
		FolderSyncInfo info = local.getFolderSyncInfo();
		if (info == null) {
			bytes = null;
		} else {
			// Use the folder sync from the workspace and the tag from the store
            MutableFolderSyncInfo newInfo = info.cloneMutable();
            newInfo.setTag(tag);
            newInfo.setStatic(false);
			bytes = newInfo.getBytes();
		}
		return bytes;
	}
	
	private boolean hasLocalSyncInfo(IContainer folder) {
		ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(folder);
		try {
			return local.getFolderSyncInfo() != null;
		} catch (CVSException e) {
			// Say that there is sync info and let the failure occur elsewhere
			return true;
		}
	}

	public CVSTag getTag(IResource resource) {
		return tag;
	}

	/**
	 * Dispose of the underlying byte store
	 */
	public void dispose() {
		getByteStore().dispose();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setVariant(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant)
	 */
	protected boolean setVariant(IResource local, IResourceVariant remote) throws TeamException {
		if (local.getType() == IResource.FOLDER && remote != null 
				&& !hasLocalSyncInfo((IFolder)local)
				&& hasLocalSyncInfo(local.getParent())) {
			// Manage the folder locally since folders exist in all versions, etc
			// Use the info from the remote except get the tag from the local parent
			CVSTag tag = CVSWorkspaceRoot.getCVSFolderFor(local.getParent()).getFolderSyncInfo().getTag();
			FolderSyncInfo info = FolderSyncInfo.getFolderSyncInfo(remote.asBytes());
            MutableFolderSyncInfo newInfo = info.cloneMutable();
            newInfo.setTag(tag);
			ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IFolder)local);
			cvsFolder.setFolderSyncInfo(newInfo);
		}
        if (remote == null && !isManaged(local)) {
            // Do not record the lack of existence of a remote for unmanaged local files
            // Instead, just flush the remote bytes if there are any
        	boolean changed = getByteStore().getBytes(local) != null;
            flushVariants(local, IResource.DEPTH_ZERO);
            return changed;
        } else {
    		boolean changed = super.setVariant(local, remote);
    		if (local.getType() == IResource.FILE && getByteStore().getBytes(local) != null && !parentHasSyncBytes(local)) {
    			// Log a warning if there is no sync bytes available for the resource's
    			// parent but there is valid sync bytes for the child
    			CVSProviderPlugin.log(new TeamException(NLS.bind(CVSMessages.ResourceSynchronizer_missingParentBytesOnSet, new String[] { getSyncName(getByteStore()), local.getFullPath().toString() }))); 
    		}
    		return changed;
        }
	}
	
	private boolean isManaged(IResource local) {
        try {
            return CVSWorkspaceRoot.getCVSResourceFor(local).isManaged();
        } catch (CVSException e) {
            return false;
        }
    }

    private boolean parentHasSyncBytes(IResource resource) throws TeamException {
		if (resource.getType() == IResource.PROJECT) return true;
		return getParentBytes(resource) != null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#collectedMembers(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource[])
	 */
	protected IResource[] collectedMembers(IResource local, IResource[] members) throws TeamException {
		// Look for resources that have sync bytes but are not in the resources we care about
		IResource[] resources = getStoredMembers(local);
		List children = new ArrayList();
		List changedResources = new ArrayList();
		children.addAll(Arrays.asList(members));
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (!children.contains(resource)) {
				// These sync bytes are stale. Purge them
				flushVariants(resource, IResource.DEPTH_INFINITE);
				changedResources.add(resource);
			}
		}
		return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
	}
	
	/**
	 * Return all the members of that have resource variant information associated with them,
	 * such as members that are explicitly flagged as not having a resource variant. This list
	 * is used by the collection algorithm to flush variants for which there is no local and
	 * no remote.
	 * @param local the locla resource
	 * @return the local children that have resource variant information cached
	 * @throws TeamException
	 */
	private IResource[] getStoredMembers(IResource local) throws TeamException {			
		try {
			if (local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) {
				IResource[] allChildren = ((IContainer)local).members(true /* include phantoms */);
				List childrenWithSyncBytes = new ArrayList();
				for (int i = 0; i < allChildren.length; i++) {
					IResource resource = allChildren[i];
					if (getByteStore().getBytes(resource) != null) {
						childrenWithSyncBytes.add(resource);
					}
				}
				return (IResource[]) childrenWithSyncBytes.toArray(
						new IResource[childrenWithSyncBytes.size()]);
			}
		} catch (CoreException e) {
			throw TeamException.asTeamException(e);
		}
		return new IResource[0];
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.core.variants.AbstractResourceVariantTree#refresh(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IResource[] refresh(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
		IResource[] changedResources = null;
		monitor.beginTask(null, 100);
		// Wait while a build is running
		// Initially wait for a short time and then increase the wait 
		// if the build is still running
		int count = 0;
		int waitTime = 10;
		while (count < 15 
				&& (isJobInFamilyRunning(ResourcesPlugin.FAMILY_AUTO_BUILD)
				|| isJobInFamilyRunning(ResourcesPlugin.FAMILY_MANUAL_BUILD))) {
			try {
				Thread.sleep(waitTime);
			} catch (InterruptedException e) {
				// Conitinue
			}	
			count++;
			if (count >= 10) {
			    waitTime = 1000;
			} else if (count >= 5) {
			    waitTime = 100;
			}
			Policy.checkCanceled(monitor);
		}
		try {
			changedResources = super.refresh(resource, depth, Policy.subMonitorFor(monitor, 99));
		} catch (TeamException e) {
		    // Try to properly handle exceptions that are due to project modifications
		    // performed while the refresh was happening
			if (!resource.getProject().isAccessible()) {
				// The project is closed so silently skip it
				return new IResource[0];
			}
			throw e;
		} finally {
			monitor.done();
		}
		if (changedResources == null) return new IResource[0];
		return changedResources;
	}
	
	private boolean isJobInFamilyRunning(Object family) {
		Job[] jobs = Platform.getJobManager().find(family);
		if (jobs != null && jobs.length > 0) {
			for (int i = 0; i < jobs.length; i++) {
				Job job = jobs[i];
				if (job.getState() != Job.NONE) {
					return true;
				}
			}
		}
		return false;
	}
	
	
	public ICVSRemoteResource buildTree(RemoteFolderTree parent, IResource resource, boolean immutable, IProgressMonitor monitor) throws TeamException {
		
		Policy.checkCanceled(monitor);
		
		byte[] remoteBytes = getByteStore().getBytes(resource);
		if (remoteBytes == null) {
			// There is no remote handle for this resource
			return null;
		}
		
		if (resource.getType() == IResource.FILE) {
			if (immutable) {
				remoteBytes = ResourceSyncInfo.setTag(remoteBytes, new CVSTag(ResourceSyncInfo.getRevision(remoteBytes), CVSTag.VERSION));
			}
			if (parent == null) {
				return (ICVSRemoteResource)getResourceVariant(resource);
			}
			return new RemoteFile(parent, remoteBytes);
		} else {
			RemoteFolderTree remote = RemoteFolderTree.fromBytes(parent, resource, remoteBytes);
			IResource[] members = members(resource);
			List children = new ArrayList();
			for (int i = 0; i < members.length; i++) {
				IResource member = members[i];
				ICVSRemoteResource child = buildTree(remote, member, immutable, monitor);
				if (child != null)
					children.add(child);
			}
			
			// Add the children to the remote folder tree
			remote.setChildren((ICVSRemoteResource[])children.toArray(new ICVSRemoteResource[children.size()]));
			return remote;
		}
	}

	public boolean isCacheFileContentsHint() {
		return cacheFileContentsHint;
	}
}
