/*******************************************************************************
 * Copyright (c) 2000, 2004 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.resources;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.FileNameMatcher;
import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter;

/**
 * This cache uses session properties to hold the bytes representing the sync
 * info. In addition when the workbench closes or a project is closed, the dirty 
 * state for all cvs managed folders are persisted using the resource's plugin
 * synchronizer.
 */
/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache implements ISaveParticipant {
	
	// key used on a folder to indicate that the resource sync has been cahced for it's children
	private static final QualifiedName RESOURCE_SYNC_CACHED_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync-cached"); //$NON-NLS-1$
	private static final Object RESOURCE_SYNC_CACHED = new Object();
	
	/*package*/ static final FileNameMatcher NULL_IGNORES = new FileNameMatcher();
	private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("dummy-repo", "dummy-root", null, false); //$NON-NLS-1$ //$NON-NLS-2$
	
	private QualifiedName FOLDER_DIRTY_STATE_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-dirty-state-cached"); //$NON-NLS-1$
	
	// defer to the sychronizer if there is no sync info
	// (i.e. for those cases where a deleted resource is recreated)
	private SynchronizerSyncInfoCache synchronizerCache;
	
	/*package*/ SessionPropertySyncInfoCache(SynchronizerSyncInfoCache synchronizerCache) {
		this.synchronizerCache = synchronizerCache;
		try {
			// this save participant is removed when the plugin is shutdown.			
			ResourcesPlugin.getWorkspace().addSaveParticipant(CVSProviderPlugin.getPlugin(), this);
			ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer();
			synchronizer.add(FOLDER_DIRTY_STATE_KEY);
		} catch (CoreException e) {
			CVSProviderPlugin.log(e);
		}
	}

	/**
	 * If not already cached, loads and caches the folder ignores sync for the container.
	 * Folder must exist and must not be the workspace root.
	 *
	 * @param container the container
	 * @return the folder ignore patterns, or an empty array if none
	 */
	/*package*/ FileNameMatcher getFolderIgnores(IContainer container, boolean threadSafeAccess) throws CVSException {
		// don't try to load if the information is already cached
		FileNameMatcher matcher = (FileNameMatcher)safeGetSessionProperty(container, IGNORE_SYNC_KEY);
		if (threadSafeAccess && matcher == null) {
			// read folder ignores and remember it
			String[] ignores = SyncFileWriter.readCVSIgnoreEntries(container);
			if (ignores == null) {
				matcher = NULL_IGNORES;
			} else {
				matcher = new FileNameMatcher(ignores);
			}
			safeSetSessionProperty(container, IGNORE_SYNC_KEY, matcher);
		}
		return matcher;
	}
    
    /* package */ boolean isIgnoresCached(IContainer container) throws CVSException {
        return safeGetSessionProperty(container, IGNORE_SYNC_KEY) != null;
    }

	/*package*/ boolean isFolderSyncInfoCached(IContainer container) throws CVSException {
		Object info = safeGetSessionProperty(container, FOLDER_SYNC_KEY);
		if (info == null){
			// Defer to the synchronizer in case the folder was recreated
			info = synchronizerCache.getCachedFolderSync(container, true);
		}
		return info != null;
	}

	/*package*/ boolean isResourceSyncInfoCached(IContainer container) throws CVSException {
		return safeGetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY) != null;
	}
	
	/*package*/ void setResourceSyncInfoCached(IContainer container) throws CVSException {
		safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, RESOURCE_SYNC_CACHED);
	}

	/**
	 * Returns the folder sync info for the container; null if none.
	 * Folder must exist and must not be the workspace root.
	 * The folder sync info for the container MUST ALREADY BE CACHED.
	 * @param container the container
	 * @param threadSafeAccess if false, the return value can only be used if not null
	 * @return the folder sync info for the folder, or null if none.
	 * @see #cacheFolderSync
	 */
	FolderSyncInfo getCachedFolderSync(IContainer container, boolean threadSafeAccess) throws CVSException {
		FolderSyncInfo info = (FolderSyncInfo)safeGetSessionProperty(container, FOLDER_SYNC_KEY);
        // If we are not thread safe, just return whatever was found in the session property
        if (!threadSafeAccess)
            return info == NULL_FOLDER_SYNC_INFO ? null : info;
		if (info == null) {
			// Defer to the synchronizer in case the folder was recreated
			info = synchronizerCache.getCachedFolderSync(container, true);
			if (info != null) {
				safeSetSessionProperty(container, FOLDER_SYNC_KEY, info);
			}
		}
		if (info == null) {
			// There should be sync info but it was missing. Report the error
			throw new CVSException(NLS.bind(CVSMessages.EclipseSynchronizer_folderSyncInfoMissing, new String[] { container.getFullPath().toString() })); //$NON-NLS-1$
		}
		if (info == NULL_FOLDER_SYNC_INFO) return null;
		return info;
	}

	/**
	 * Purges the cache recursively for all resources beneath the container.
	 * There must not be any pending uncommitted changes.
	 * @return the resources whose sync info was flushed
	 */
	/*package*/ IResource[] purgeCache(IContainer container, boolean deep) throws CVSException {
		if (! container.exists()) return new IResource[0];
		try {
			Set flushed = new HashSet();
			if (container.getType() != IResource.ROOT) {
				safeSetSessionProperty(container, IGNORE_SYNC_KEY, null);
				safeSetSessionProperty(container, FOLDER_SYNC_KEY, null);
				safeSetSessionProperty(container, RESOURCE_SYNC_CACHED_KEY, null);
				flushed.add(container);
				EclipseSynchronizer.getInstance().adjustDirtyStateRecursively(container, RECOMPUTE_INDICATOR);
			}
			IResource[] members = container.members();
			for (int i = 0; i < members.length; i++) {
				IResource resource = members[i];
				purgeResourceSyncCache(resource);
				flushed.add(resource);
				if (deep && resource.getType() != IResource.FILE) {
					IResource[] flushedChildren = purgeCache((IContainer) resource, deep);
					flushed.addAll(Arrays.asList(flushedChildren));
				}
			}
			return (IResource[]) flushed.toArray(new IResource[flushed.size()]);
		} catch (CoreException e) {
			throw CVSException.wrapException(e);
		}
	}
	
	/* package*/ void purgeResourceSyncCache(IResource resource) throws CVSException {
		safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, null);
		EclipseSynchronizer.getInstance().adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR);
	}
	
	/**
	 * Sets the array of folder ignore patterns for the container, must not be null.
	 * Folder must exist and must not be the workspace root.
	 *
	 * @param container the container
	 * @param ignores the array of ignore patterns
	 */
	/*package*/ void setCachedFolderIgnores(IContainer container, String[] ignores) throws CVSException {
		safeSetSessionProperty(container, IGNORE_SYNC_KEY, new FileNameMatcher(ignores));
	}


	/**
	 * Sets the folder sync info for the container; if null, deletes it.
	 * Folder must exist and must not be the workspace root.
	 * The folder sync info for the container need not have previously been cached.
	 *
	 * @param container the container
	 * @param info the new folder sync info
	 */
	void setCachedFolderSync(IContainer container, FolderSyncInfo info, boolean canModifyWorkspace) throws CVSException {
		if (!container.exists()) return;
		if (info == null) {
			info = NULL_FOLDER_SYNC_INFO;
		} 
		safeSetSessionProperty(container, FOLDER_SYNC_KEY, info);
		// Ensure the synchronizer is clear for exiting resources
		if (canModifyWorkspace && synchronizerCache.getCachedFolderSync(container, true) != null) {
			synchronizerCache.setCachedFolderSync(container, null, true);
		}
	}

	/*package*/ void setDirtyIndicator(IResource resource, String indicator) throws CVSException {
		if (resource.getType() == IResource.FILE) {
			internalSetDirtyIndicator((IFile)resource, indicator);
		} else {
			internalSetDirtyIndicator((IContainer)resource, indicator);
		}
	}
	/*package*/ String getDirtyIndicator(IResource resource, boolean threadSafeAccess) throws CVSException {
		if (resource.getType() == IResource.FILE) {
			return internalGetDirtyIndicator((IFile)resource, threadSafeAccess);
		} else {
			return internalGetDirtyIndicator((IContainer)resource, threadSafeAccess);
		}
	}
	
	private void internalSetDirtyIndicator(IFile file, String indicator) throws CVSException {
		safeSetSessionProperty(file, IS_DIRTY, indicator);
	}
	
	private String internalGetDirtyIndicator(IFile file, boolean threadSafeAccess) throws CVSException {
		String di = (String)safeGetSessionProperty(file, IS_DIRTY);
		if(di == null) {
			di = RECOMPUTE_INDICATOR;
		}
		return di;
	}

	private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException {
		safeSetSessionProperty(container, IS_DIRTY, indicator);
	}
	
	private String internalGetDirtyIndicator(IContainer container, boolean threadSafeAccess) throws CVSException {
		try {
			String di = (String)safeGetSessionProperty(container, IS_DIRTY);
			
			// if the session property is not available then restore from persisted sync info. At this
			// time the sync info is not flushed because we don't want the workspace to generate
			// a delta.			
			if(di == null) {
				byte [] diBytes = ResourcesPlugin.getWorkspace().getSynchronizer().getSyncInfo(FOLDER_DIRTY_STATE_KEY, container);
				if(diBytes != null && !CVSProviderPlugin.getPlugin().crashOnLastRun()) {
					di = new String(diBytes);
					if(di.equals(NOT_DIRTY_INDICATOR)) {
						di = NOT_DIRTY_INDICATOR;
					} else if(di.equals(IS_DIRTY_INDICATOR)) {
						di = IS_DIRTY_INDICATOR;
					} else {
						di = RECOMPUTE_INDICATOR;
					}
				} else {
					di = RECOMPUTE_INDICATOR;
				}
                // Only set the session property if we are thread safe
                if (threadSafeAccess) {
                    setDirtyIndicator(container, di);
                }
			}
			return di;
		} catch (CoreException e) {
			throw CVSException.wrapException(e);
		}
	}
		
	/*
	 * Flush dirty cache for the resource
	 */
	/*package*/ void flushDirtyCache(IResource resource) throws CVSException {
		if (resource.exists()) {
			if (resource.getType() == IResource.FILE) {
				safeSetSessionProperty(resource, IS_DIRTY, null);
			} else {
				safeSetSessionProperty(resource, IS_DIRTY, null);
				flushDirtyStateFromDisk((IContainer)resource);
			}
		}
	}
	
	/**
	 * Method isSyncInfoLoaded returns true if all the sync info for the
	 * provided resources is loaded into the internal cache.
	 *
	 * @param resources
	 * @param i
	 * @return boolean
	 */
	/*package*/ boolean isSyncInfoLoaded(IContainer parent) throws CVSException {
		if (parent.getFolder(new Path(SyncFileWriter.CVS_DIRNAME)).exists()) {
			if (safeGetSessionProperty(parent, RESOURCE_SYNC_CACHED_KEY) == null)
				return false;
			if (safeGetSessionProperty(parent, FOLDER_SYNC_KEY) == null)
				return false;
//				if (parent.getSessionProperty(IGNORE_SYNC_KEY) == null)
//					return false;
		}
		return true;
	}
	
	/**
	 * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#getCachedSyncBytes(org.eclipse.core.resources.IResource, boolean)
	 */
	byte[] getCachedSyncBytes(IResource resource, boolean threadSafeAccess) throws CVSException {
		byte[] bytes = (byte[])safeGetSessionProperty(resource, RESOURCE_SYNC_KEY);
		// If we are not thread safe, just return whatever was found in the session property
        if (!threadSafeAccess)
            return bytes;
		if (bytes == null) {
			// Defer to the synchronizer in case the file was recreated
			bytes = synchronizerCache.getCachedSyncBytes(resource, true);
			if (bytes != null) {
				boolean genderChange = false;
				if (resource.getType() == IResource.FILE) {
					if (ResourceSyncInfo.isFolder(bytes)) {
						genderChange = true;
					}
				} else if (!ResourceSyncInfo.isFolder(bytes)) {
					genderChange = true;
				}
				if (genderChange) {
					// Return null if it is a gender change
					bytes = null;
				} else {
					safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, ResourceSyncInfo.convertFromDeletion(bytes));
				}
			}
		}
		return bytes;
	}

	Object safeGetSessionProperty(IResource resource, QualifiedName key) throws CVSException {
		try {
			return resource.getSessionProperty(key);
		} catch (CoreException e) {
			IStatus status = e.getStatus();
			if(status != null) {
				int code = e.getStatus().getCode();
				if(code != IResourceStatus.RESOURCE_NOT_LOCAL ||
					code != IResourceStatus.RESOURCE_NOT_FOUND) {
						// ignore error since a phantom would of been created
						// and we can safely ignore these cases
						return null;
				}
			}
			// some other error we did not expect
			throw CVSException.wrapException(e);
		}
	}
	
	void safeSetSessionProperty(IResource resource, QualifiedName key, Object value) throws CVSException {
			try {
				resource.setSessionProperty(key, value);
			} catch (CoreException e) {
				throw CVSException.wrapException(e);
			}
		}
	
	/**
	 * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#setCachedSyncBytes(org.eclipse.core.resources.IResource, byte[])
	 */
	void setCachedSyncBytes(IResource resource, byte[] syncBytes, boolean canModifyWorkspace) throws CVSException {
		// Ensure that the sync bytes do not indicate a deletion
		if (syncBytes != null && ResourceSyncInfo.isDeletion(syncBytes)) {
			syncBytes = ResourceSyncInfo.convertFromDeletion(syncBytes);
		}
		// Put the sync bytes into the cache
		safeSetSessionProperty(resource, RESOURCE_SYNC_KEY, syncBytes);
		// Ensure the synchronizer is clear
		if (canModifyWorkspace && synchronizerCache.getCachedSyncBytes(resource, true) != null) {
			synchronizerCache.setCachedSyncBytes(resource, null, canModifyWorkspace);
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
	 */
	public void doneSaving(ISaveContext context) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
	 */
	public void prepareToSave(ISaveContext context) throws CoreException {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
	 */
	public void rollback(ISaveContext context) {			
	}

	/* Called when the workbench is shutdown or projects are closed. The dirty state
	 * of folders is persisted, using sync info, so that at startup or project open
	 * the folder state can be quickly calculated. This is mainly for improving decorator
	 * performance.
	 * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
	 */
	public void saving(ISaveContext context) throws CoreException {
		boolean fullSave = (context.getKind() == ISaveContext.FULL_SAVE);
		boolean projectSave = (context.getKind() == ISaveContext.PROJECT_SAVE);
		
		if((projectSave || fullSave)) {
			// persist all session properties for folders into sync info.
			final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer();
		
			// traverse the workspace looking for CVS managed projects or just the 
			// specific projects being closed
			IProject[] projects;
			if(projectSave) {
				projects = new IProject[1];
				projects[0] = context.getProject();
			} else {
				projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
			}
			for (int i = 0; i < projects.length; i++) {
				IProject project = projects[i];
				RepositoryProvider provider = RepositoryProvider.getProvider(
														project,
														CVSProviderPlugin.getTypeId());
														
				// found a project managed by CVS, convert each session property on a
				// folder to a sync object.
				if (provider != null) {
					project.accept(new IResourceVisitor() {
						public boolean visit(IResource resource) throws CoreException {
							if(resource.getType() != IResource.FILE) {
								String di = null;
								try {
									di = getDirtyIndicator(resource, true);
								} catch (CVSException e) {
									// continue traversal
									CVSProviderPlugin.log(e);
								}
								if(di != null) {
									synchronizer.setSyncInfo(FOLDER_DIRTY_STATE_KEY, resource, di.getBytes());
								}								
							}
							return true;
						}
					});
				}
			}
		}
	}
		
	/* 
	 * Called to clear the folder dirty state from the resource sync tree and stop persisting
	 * these values to disk.
	 */
	private void flushDirtyStateFromDisk(IContainer container) {
		final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer();									
		try {
			synchronizer.flushSyncInfo(FOLDER_DIRTY_STATE_KEY, container, IResource.DEPTH_INFINITE);
		} catch (CoreException e) {
			CVSProviderPlugin.log(e);
		}
	}

	/*
	 * Flush all the cahced dirty state for the resource and its members.
	 */
	/* package*/ void purgeDirtyCache(IResource resource) throws CVSException {
		if (! resource.exists()) return;
		try {
			if (resource.getType() != IResource.ROOT) {
				safeSetSessionProperty(resource, IS_DIRTY, null);
			}
			if (resource.getType() != IResource.FILE) {
				ResourcesPlugin.getWorkspace().getSynchronizer().flushSyncInfo(FOLDER_DIRTY_STATE_KEY, resource, IResource.DEPTH_INFINITE);
				IResource[] members = ((IContainer)resource).members();
				for (int i = 0; i < members.length; i++) {
					purgeDirtyCache(members[i]);
				}
			}
		} catch (CoreException e) {
			throw CVSException.wrapException(e);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#cachesDirtyState()
	 */
	public boolean cachesDirtyState() {
		return true;
	}
}
