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

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.core.Policy;
import org.eclipse.team.internal.core.subscribers.BatchingLock;
import org.eclipse.team.internal.core.subscribers.SyncByteConverter;
import org.eclipse.team.internal.core.subscribers.BatchingLock.IFlushOperation;
import org.eclipse.team.internal.core.subscribers.BatchingLock.ThreadInfo;

/**
 * This class manages the synchronization between local resources and their
 * corresponding resource variants. It provides the following:
 * <ul>
 * <li>Three way synchronization (set base, set remote, ignored)
 * <li>Resource traversal (members)
 * <li>Change events and event batching (run)
 * <li>Thread-safety
 * </ul>
 *
 * @since 3.0
 */
public class ThreeWaySynchronizer {

	private IFlushOperation flushOperation = new IFlushOperation() {
		/**
		 * Callback which is invoked when the batching resource lock is released
		 * or when a flush is requested (see beginBatching(IResource)).
		 *
		 * @see BatchingLock#flush(IProgressMonitor)
		 */
		@Override
		public void flush(ThreadInfo info, IProgressMonitor monitor)
				throws TeamException {
			if (info != null && !info.isEmpty()) {
				broadcastSyncChanges(info.getChangedResources());
			}
		}
	};

	private static final byte[] IGNORED_BYTES = "i".getBytes(); //$NON-NLS-1$

	private ILock lock = Job.getJobManager().newLock();
	private BatchingLock batchingLock = new BatchingLock();
	private ResourceVariantByteStore cache;
	private Set<ISynchronizerChangeListener> listeners = new HashSet<>();

	/**
	 * Create a three-way synchronizer that uses a persistent
	 * byte store with the given qualified name as its unique
	 * identifier.
	 * @param name the unique identifier for the persistent store
	 */
	public ThreeWaySynchronizer(QualifiedName name) {
		this(new PersistantResourceVariantByteStore(name));
	}

	/**
	 * Create a three-way synchronizer that uses the given byte store
	 * as its underlying byte cache.
	 * @param store the byte store this synchronizer uses to cache its bytes
	 */
	public ThreeWaySynchronizer(ResourceVariantByteStore store) {
		cache = store;
	}

	/**
	 * Adds a listener to this synchronizer. Listeners will be notified
	 * when the synchronization state of a resource changes. Listeners
	 * are not notified when files are modified locally. Clients can
	 * make use of the <code>IResource</code> delta mechanism if they
	 * need to know about local modifications.
	 * 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 synchronizer change listener
	 */
	public void addListener(ISynchronizerChangeListener listener) {
		synchronized (listeners) {
			listeners.add(listener);
		}
	}

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

	/**
	 * Return the base bytes that are cached for the given resource
	 * or <code>null</code> if no base is cached. The returned bytes
	 * should uniquely identify the resource variant that is the base
	 * for the given local resource.
	 *
	 * @param resource the resource
	 * @return the base bytes cached with the resource or <code>null</code>
	 * @throws TeamException
	 */
	public byte[] getBaseBytes(IResource resource) throws TeamException {
		try {
			beginOperation();
			byte[] syncBytes = internalGetSyncBytes(resource);
			if (syncBytes == null) return null;
			byte[] baseBytes = getSlot(syncBytes, 1);
			if (baseBytes == null || baseBytes.length == 0) return null;
			return baseBytes;
		} finally {
			endOperation();
		}
	}

	/**
	 * Set the base bytes for the given resource. The provided bytes
	 * should encode enough information to uniquely identify
	 * (and possibly recreate) the resource variant that is the base
	 * for the given local resource. In essence, setting the base
	 * bytes is equivalent to marking the file as in-sync. As such,
	 * setting the base bytes will also set the remote bytes and mark
	 * the file as clean (i.e. having no outgoing changes).
	 *
	 * @param resource the resource
	 * @param baseBytes the base bytes that identify the base resource variant
	 * @throws TeamException
	 */
	public void setBaseBytes(IResource resource, byte[] baseBytes) throws TeamException {
		Assert.isNotNull(baseBytes);
		ISchedulingRule rule = null;
		try {
			rule = beginBatching(resource, null);
			try {
				beginOperation();
				String base = new String(baseBytes);
				String[] slots = new String[] {
						Long.valueOf(resource.getModificationStamp()).toString(),
						base,
						base
				};
				byte[] syncBytes = toBytes(slots);
				internalSetSyncBytes(resource, syncBytes);
				batchingLock.resourceChanged(resource);
			} finally {
				endOperation();
			}
		} finally {
			if (rule != null) endBatching(rule, null);
		}
	}

	/**
	 * Return whether the local resource has been modified since the last time
	 * the base bytes were set. This method will return <code>false</code>
	 * for ignored resources and <code>true</code> for non-existant resources
	 * that have base bytes cached.
	 * @param resource the resource
	 * @return <code>true</code> if the resource has been modified since the
	 * last time the base bytes were set.
	 * @throws TeamException
	 */
	public boolean isLocallyModified(IResource resource) throws TeamException {
		return ((internalGetSyncBytes(resource) == null && ! isIgnored(resource)) ||
				(getLocalTimestamp(resource) != resource.getModificationStamp()) ||
				(getBaseBytes(resource) != null && !resource.exists()));
	}

	/**
	 * Return the remote bytes that are cached for the given resource
	 * or <code>null</code> if no remote is cached. The returned bytes
	 * should uniquely identify the resource variant that is the remote
	 * for the given local resource.
	 *
	 * @param resource the resource
	 * @return the remote bytes cached with the resource or <code>null</code>
	 * @throws TeamException
	 */
	public byte[] getRemoteBytes(IResource resource) throws TeamException {
		try {
			beginOperation();
			byte[] syncBytes = internalGetSyncBytes(resource);
			if (syncBytes == null) return null;
			byte[] remoteBytes = getSlot(syncBytes, 2);
			if (remoteBytes == null || remoteBytes.length == 0) return null;
			return remoteBytes;
		} finally {
			endOperation();
		}
	}

	/**
	 * Set the remote bytes for the given resource. The provided bytes
	 * should encode enough information to uniquely identify
	 * (and possibly recreate) the resource variant that is the remote
	 * for the given local resource. If the remote for a resource
	 * no longer exists, <code>removeRemoteBytes(IResource)</code>
	 * should be called.
	 *
	 * @param resource the resource
	 * @param remoteBytes the base bytes that identify the remote resource variant
	 * @return <code>true</code> if the remote bytes changed as a result of the set
	 * @throws TeamException
	 */
	public boolean setRemoteBytes(IResource resource, byte[] remoteBytes) throws TeamException {
		Assert.isNotNull(remoteBytes);
		ISchedulingRule rule = null;
		try {
			rule = beginBatching(resource, null);
			try {
				beginOperation();
				byte[] syncBytes = internalGetSyncBytes(resource);
				if (syncBytes == null) {
					String[] slots = new String[] {
							"", //$NON-NLS-1$
							"", //$NON-NLS-1$
							new String(remoteBytes)
					};
					syncBytes = toBytes(slots);
				} else {
					byte[] currentRemote = getSlot(syncBytes, 2);
					if (equals(remoteBytes, currentRemote)) return false;
					syncBytes = setSlot(syncBytes, 2, remoteBytes);
				}
				internalSetSyncBytes(resource, syncBytes);
				batchingLock.resourceChanged(resource);
				return true;
			} finally {
				endOperation();
			}
		} finally {
			if (rule != null) endBatching(rule, null);
		}
	}

	/**
	 * Remove the remote bytes associated with the resource. This is typically
	 * done when the corresponding remote resource variant no longer exists.
	 * @param resource the resource
	 * @return <code>true</code> if the remote bytes changed as a result of the removal
	 * @throws TeamException
	 */
	public boolean removeRemoteBytes(IResource resource) throws TeamException {
		ISchedulingRule rule = null;
		try {
			rule = beginBatching(resource, null);
			try {
				beginOperation();
				byte[] syncBytes = internalGetSyncBytes(resource);
				if (syncBytes != null) {
					String currentRemote = new String(getSlot(syncBytes, 2));
					if (currentRemote.length() == 0) return false;
					syncBytes = setSlot(syncBytes, 2, new byte[0]);
					internalSetSyncBytes(resource, syncBytes);
					batchingLock.resourceChanged(resource);
					return true;
				}
				return false;
			} finally {
				endOperation();
			}
		} finally {
			if (rule != null) endBatching(rule, null);
		}
	}

	/**
	 * Return whether the given resource has sync bytes in the synchronizer.
	 * @param resource the local resource
	 * @return whether there are sync bytes cached for the local resources.
	 * @throws TeamException
	 */
	public boolean hasSyncBytes(IResource resource) throws TeamException {
		return internalGetSyncBytes(resource) != null;
	}

	/**
	 * Returns whether the resource has been marked as ignored
	 * using <code>setIgnored(IResource)</code>.
	 * @param resource the resource
	 * @return <code>true</code> if the resource is ignored.
	 * @throws TeamException
	 */
	public boolean isIgnored(IResource resource) throws TeamException {
		byte[] bytes = cache.getBytes(resource);
		return (bytes != null && equals(bytes, IGNORED_BYTES));
	}

	/**
	 * Mark the resource as being ignored. Ignored resources
	 * are not returned by the <code>members</code> method,
	 * are never dirty (see <code>isLocallyModified</code>) and
	 * do not have base or remote bytes cached for them.
	 * @param resource the resource to be ignored
	 * @throws TeamException
	 */
	public void setIgnored(IResource resource) throws TeamException {
		internalSetSyncBytes(resource, IGNORED_BYTES);
	}

	/**
	 * Return the members of the local resource that either have sync bytes
	 * or exist locally and are not ignored.
	 * @param resource the local resource
	 * @return the children of the local resource that have cached sync bytes
	 * or are not ignored
	 * @throws TeamException
	 */
	public IResource[] members(IResource resource) throws TeamException {
		if (resource.getType() == IResource.FILE) {
			return new IResource[0];
		}
		try {
			Set<IResource> potentialChildren = new HashSet<>();
			IContainer container = (IContainer)resource;
			if (container.exists()) {
				potentialChildren.addAll(Arrays.asList(container.members()));
			}
			potentialChildren.addAll(Arrays.asList(cache.members(resource)));
			List<IResource> result = new ArrayList<>();
			for (IResource child : potentialChildren) {
				if (child.exists() || hasSyncBytes(child)) {
					result.add(child);
				}
			}
			return result.toArray(new IResource[result.size()]);
		} catch (CoreException e) {
			throw TeamException.asTeamException(e);
		}
	}

	/**
	 * Flush any cached bytes for the given resource to the depth specified.
	 * @param resource the resource
	 * @param depth the depth of the flush (one of <code>IResource.DEPTH_ZERO</code>,
	 * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
	 * @throws TeamException
	 */
	public void flush(IResource resource, int depth) throws TeamException {
		ISchedulingRule rule = null;
		try {
			rule = beginBatching(resource, null);
			try {
				beginOperation();
				if (cache.flushBytes(resource, depth)) {
					batchingLock.resourceChanged(resource);
				}
			} finally {
				endOperation();
			}
		} finally {
			if (rule != null) endBatching(rule, null);
		}
	}

	/**
	 * Perform multiple sync state modifications and fire only a single change notification
	 * at the end.
	 * @param resourceRule the scheduling rule that encompasses all modifications
	 * @param runnable the runnable that performs the sync state modifications
	 * @param monitor a progress monitor
	 * @throws TeamException
	 */
	public void run(IResource resourceRule, IWorkspaceRunnable runnable, IProgressMonitor monitor) throws TeamException {
		monitor = Policy.monitorFor(monitor);
		monitor.beginTask(null, 100);
		ISchedulingRule rule = beginBatching(resourceRule, Policy.subMonitorFor(monitor, 10));
		try {
			cache.run(resourceRule, runnable, Policy.subMonitorFor(monitor, 80));
		} catch (CoreException e) {
			throw TeamException.asTeamException(e);
		} finally {
			if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 10));
			monitor.done();
		}
	}

	private void broadcastSyncChanges(final IResource[] resources) {
		ISynchronizerChangeListener[] allListeners;
		// Copy the listener list so we're not calling client code while synchronized
		synchronized(listeners) {
			allListeners = listeners.toArray(new ISynchronizerChangeListener[listeners.size()]);
		}
		// Notify the listeners safely so all will receive notification
		for (int i = 0; i < allListeners.length; i++) {
			final ISynchronizerChangeListener 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.syncStateChanged(resources);

				}
			});
		}
	}

	/*
	 * Return the cached sync bytes for the given resource.
	 * The value <code>null</code> is returned if there is no
	 * cached bytes or if the resource is ignored.
	 */
	private byte[] internalGetSyncBytes(IResource resource) throws TeamException {
		byte[] bytes = cache.getBytes(resource);
		if (bytes != null && equals(bytes, IGNORED_BYTES)) return null;
		return bytes;
	}

	/*
	 * Set the cached sync bytes
	 */
	private boolean internalSetSyncBytes(IResource resource, byte[] syncBytes) throws TeamException {
		return cache.setBytes(resource, syncBytes);
	}

	private byte[] getSlot(byte[] syncBytes, int i) {
		return SyncByteConverter.getSlot(syncBytes, i, false);
	}

	private byte[] setSlot(byte[] syncBytes, int i, byte[] insertBytes) throws TeamException {
		return SyncByteConverter.setSlot(syncBytes, i, insertBytes);
	}

	private byte[] toBytes(String[] slots) {
		return SyncByteConverter.toBytes(slots);
	}

	private long getLocalTimestamp(IResource resource) throws TeamException {
		try {
			beginOperation();
			byte[] syncBytes = internalGetSyncBytes(resource);
			if (syncBytes == null) return -1;
			byte[] bytes = getSlot(syncBytes, 0);
			if (bytes == null || bytes.length == 0) return -1;
			return Long.parseLong(new String(bytes));
		} finally {
			endOperation();
		}
	}

	private boolean equals(byte[] syncBytes, byte[] oldBytes) {
		if (syncBytes.length != oldBytes.length) return false;
		for (int i = 0; i < oldBytes.length; i++) {
			if (oldBytes[i] != syncBytes[i]) return false;
		}
		return true;
	}

	/*
	 * Begin an access to the internal data structures of the synchronizer
	 */
	private void beginOperation() {
		// Do not try to acquire the lock if the resources tree is locked
		// The reason for this is that during the resource delta phase (i.e. when the tree is locked)
		// the workspace lock is held. If we obtain our lock, there is
		// a chance of deadlock. It is OK if we don't as we are still protected
		// by scheduling rules and the workspace lock.
		if (ResourcesPlugin.getWorkspace().isTreeLocked()) return;
		lock.acquire();
	}

	/*
	 * End an access to the internal data structures of the synchronizer
	 */
	private void endOperation() {
		// See beginOperation() for a description of why the lock is not obtained when the tree is locked
		if (ResourcesPlugin.getWorkspace().isTreeLocked()) return;
		lock.release();
	}

	/*
	 * Begins a batch of operations in order to batch event changes.
	 * The provided scheduling rule indicates the resources
	 * that the resources affected by the operation while the returned scheduling rule
	 * is the rule obtained by the lock. It may differ from the provided rule.
	 */
	private ISchedulingRule beginBatching(ISchedulingRule resourceRule, IProgressMonitor monitor) {
		return batchingLock.acquire(resourceRule, flushOperation /* IFlushOperation */, monitor);
	}

	/*
	 * Ends a batch of operations. The provided rule must be the one that was returned
	 * by the corresponding call to beginBatching.
	 */
	private void endBatching(ISchedulingRule rule, IProgressMonitor monitor) throws TeamException {
		batchingLock.release(rule, monitor);
	}
}
