/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core;

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.core.TeamException;
import org.eclipse.team.core.subscribers.*;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.synchronize.SyncInfoFilter;
import org.eclipse.team.core.variants.*;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
import org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantTree;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Util;

/**
 * A CVSMergeSubscriber is responsible for maintaining the remote trees for a merge into
 * the workspace. The remote trees represent the CVS revisions of the start and end
 * points (version or branch) of the merge.
 * 
 * This subscriber stores the remote handles in the resource tree sync info slot. When
 * the merge is cancelled this sync info is cleared.
 * 
 * A merge can persist between workbench sessions and thus can be used as an
 * ongoing merge.
 * 
 * TODO: Is the merge subscriber interested in workspace sync info changes?
 * TODO: Do certain operations (e.g. replace with) invalidate a merge subscriber?
 * TODO: How to ensure that sync info is flushed when merge roots are deleted?
 */
public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResourceChangeListener, ISubscriberChangeListener {

	private final class MergeBaseTree extends CVSResourceVariantTree {
		// The merge synchronizer has been kept so that those upgrading
		// from 3.0 M8 to 3.0 M9 so not lose there ongoing merge state
		private PersistantResourceVariantByteStore mergedSynchronizer;
		private MergeBaseTree(ResourceVariantByteStore cache, CVSTag tag, boolean cacheFileContentsHint, String syncKeyPrefix) {
			super(cache, tag, cacheFileContentsHint);
			mergedSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + "0merged")); //$NON-NLS-1$
		}
		public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
			// Only refresh the base of a resource once as it should not change
			List unrefreshed = new ArrayList();
			for (int i = 0; i < resources.length; i++) {
				IResource resource = resources[i];
				if (!hasResourceVariant(resource)) {
					unrefreshed.add(resource);
				}
			}
			if (unrefreshed.isEmpty()) {
				monitor.done();
				return new IResource[0];
			}
			IResource[] refreshed = super.refresh((IResource[]) unrefreshed.toArray(new IResource[unrefreshed.size()]), depth, monitor);
			return refreshed;
		}
		public IResourceVariant getResourceVariant(IResource resource) throws TeamException {
			// Use the merged bytes for the base if there are some
			byte[] mergedBytes = mergedSynchronizer.getBytes(resource);
			if (mergedBytes != null) {
				byte[] parentBytes = getByteStore().getBytes(resource.getParent());
				if (parentBytes != null) {
					return RemoteFile.fromBytes(resource, mergedBytes, parentBytes);
				}
			}
			return super.getResourceVariant(resource);
		}
		
		/**
		 * Mark the resource as merged by making it's base equal the remote
		 */
		public void merged(IResource resource, byte[] remoteBytes) throws TeamException {
			if (remoteBytes == null) {
				getByteStore().deleteBytes(resource);
			} else {
				getByteStore().setBytes(resource, remoteBytes);
			}
		}
		
		/**
		 * Return true if the remote has already been merged
		 * (i.e. the base equals the remote).
		 */
		public boolean isMerged(IResource resource, byte[] remoteBytes) throws TeamException {
			byte[] mergedBytes = getByteStore().getBytes(resource);
			return Util.equals(mergedBytes, remoteBytes);
		}
		
		@Override
		public void dispose() {
			mergedSynchronizer.dispose();
			super.dispose();
		}
	}

	public static final String ID = "org.eclipse.team.cvs.ui.cvsmerge-participant"; //$NON-NLS-1$
	public static final String ID_MODAL = "org.eclipse.team.cvs.ui.cvsmerge-participant-modal"; //$NON-NLS-1$
	private static final String UNIQUE_ID_PREFIX = "merge-"; //$NON-NLS-1$
	
	private CVSTag start, end;
	private List<IResource> roots;
	private CVSResourceVariantTree remoteTree;
	private MergeBaseTree baseTree;
	private boolean isModelSync;

	public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end, boolean isModelSync) {		
		this(getUniqueId(), roots, start, end);
		this.isModelSync = isModelSync;
	}

	private static QualifiedName getUniqueId() {
		String uniqueId = Long.toString(System.currentTimeMillis());
		return new QualifiedName(ID, "CVS" + UNIQUE_ID_PREFIX + uniqueId); //$NON-NLS-1$
	}
	
	public CVSMergeSubscriber(QualifiedName id, IResource[] roots, CVSTag start, CVSTag end) {		
		super(id, NLS.bind(CVSMessages.CVSMergeSubscriber_2, new String[] { start.getName(), end.getName() }));
		this.start = start;
		this.end = end;
		this.roots = new ArrayList<>(Arrays.asList(roots));
		initialize();
	}

	/*
	 * @see org.eclipse.team.internal.ccvs.core.CVSWorkspaceSubscriber#initialize()
	 */
	private void initialize() {			
		QualifiedName id = getId();
		String syncKeyPrefix = id.getLocalName();
		PersistantResourceVariantByteStore remoteSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + end.getName()));
		remoteTree = new CVSResourceVariantTree(remoteSynchronizer, getEndTag(), getCacheFileContentsHint()) {
			public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
				// Override refresh to compare file contents
				monitor.beginTask(null, 100);
				try {
					IResource[] refreshed = super.refresh(resources, depth, monitor);
					compareWithRemote(refreshed, Policy.subMonitorFor(monitor, 50));
					return refreshed;
				} finally {
					monitor.done();
				}
			}
		};
		PersistantResourceVariantByteStore baseSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + start.getName()));
		baseTree = new MergeBaseTree(baseSynchronizer, getStartTag(), getCacheFileContentsHint(), syncKeyPrefix);
		
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
		CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this);
	}

	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote) throws TeamException {
		CVSMergeSyncInfo info = new CVSMergeSyncInfo(local, base, remote, this);
		info.init();
		return info;
	}

	public void merged(IResource[] resources) throws TeamException {
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			internalMerged(resource);
		}
		fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, resources));
	}
	
	private void internalMerged(IResource resource) throws TeamException {
		byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
		baseTree.merged(resource, remoteBytes);
	}

	/*
	 * @see org.eclipse.team.core.sync.TeamSubscriber#cancel()
	 */
	public void cancel() {	
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);		
		remoteTree.dispose();
		baseTree.dispose();	
	}

	@Override
	public IResource[] roots() {
		return roots.toArray(new IResource[roots.size()]);
	}

	@Override
	public boolean isSupervised(IResource resource) throws TeamException {
		return getBaseTree().hasResourceVariant(resource) || getRemoteTree().hasResourceVariant(resource); 
	}

	public CVSTag getStartTag() {
		return start;
	}
	
	public CVSTag getEndTag() {
		return end;
	}

	boolean isModelSync() {
		return isModelSync;
	}

	/*
	 * What to do when a root resource for this merge changes?
	 * Deleted, Move, Copied
	 * Changed in a CVS way (tag changed, revision changed...)
	 * Contents changed by user
	 * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		try {
			IResourceDelta delta = event.getDelta();
			if(delta != null) {
				delta.accept(new IResourceDeltaVisitor() {
				public boolean visit(IResourceDelta delta) throws CoreException {
					IResource resource = delta.getResource();
			
					if (resource.getType()==IResource.PROJECT) {
						IProject project = (IProject)resource;
						if (!project.isAccessible()) {
							return false;
						}
						if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
							return false;
						} 
						if (RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()) == null) {
							return false;
						}
					}
			
					if (roots.contains(resource)) {
						if (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.MOVED_TO) {
							cancel();
						}
						// stop visiting children
						return false;
					}
					// keep visiting children
					return true;
				}
			});
			}
		} catch (CoreException e) {
			CVSProviderPlugin.log(e.getStatus());
		}
	}

	/**
	 * Return whether the given resource has been merged with its 
	 * corresponding remote.
	 * @param resource the local resource
	 * @return boolean
	 * @throws TeamException
	 */
	public boolean isMerged(IResource resource) throws TeamException {
		byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
		return baseTree.isMerged(resource, remoteBytes);
	}

	/* 
	 * Currently only the workspace subscriber knows when a project has been deconfigured. We will listen for these events
	 * and remove the root then forward to merge subscriber listeners.
	 * 
	 * @see org.eclipse.team.core.subscribers.ITeamResourceChangeListener#teamResourceChanged(org.eclipse.team.core.subscribers.TeamDelta[])
	 */
	public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) {		
		for (int i = 0; i < deltas.length; i++) {
			ISubscriberChangeEvent delta = deltas[i];
			switch(delta.getFlags()) {
				case ISubscriberChangeEvent.ROOT_REMOVED:
					IResource resource = delta.getResource();
					if(roots.remove(resource))	{
						fireTeamResourceChange(new ISubscriberChangeEvent[] {delta});
					}						
					break;
				default:
					break;
			}
		}
	}

	@Override
	protected IResourceVariantTree getBaseTree() {
		return baseTree;
	}

	@Override
	protected IResourceVariantTree getRemoteTree() {
		return remoteTree;
	}
	
	protected  boolean getCacheFileContentsHint() {
		return true;
	}

	/*
	 * Mark as merged any local resources whose contents match that of the remote resource.
	 */
	private void compareWithRemote(IResource[] refreshed, IProgressMonitor monitor) throws CVSException, TeamException {
		// For any remote changes, if the revision differs from the local, compare the contents.
		if (refreshed.length == 0) return;
		SyncInfoFilter.ContentComparisonSyncInfoFilter contentFilter =
			new SyncInfoFilter.ContentComparisonSyncInfoFilter();
		monitor.beginTask(null, refreshed.length * 100);
		for (int i = 0; i < refreshed.length; i++) {
			IResource resource = refreshed[i];
			if (resource.getType() == IResource.FILE) {
				ICVSFile local = CVSWorkspaceRoot.getCVSFileFor((IFile)resource);
				byte[] localBytes = local.getSyncBytes();
				byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
				if (remoteBytes != null 
						&& localBytes != null
						&& local.exists()
						&& !ResourceSyncInfo.getRevision(remoteBytes).equals(ResourceSyncInfo.getRevision(localBytes))
						&& contentFilter.select(getSyncInfo(resource), Policy.subMonitorFor(monitor, 100))) {
					// The contents are equals so mark the file as merged
					internalMerged(resource);
				}
			}
		}
		monitor.done();
	}
	
	
	private PersistantResourceVariantByteStore getRemoteByteStore() {
		return (PersistantResourceVariantByteStore)((CVSResourceVariantTree)getRemoteTree()).getByteStore();
	}
	
	@Override
	public boolean equals(Object other) {
		if(this == other) return true;
		if(! (other instanceof CVSMergeSubscriber)) return false;
		CVSMergeSubscriber s = (CVSMergeSubscriber)other;
		return getEndTag().equals(s.getEndTag()) && 
				getStartTag().equals(s.getStartTag()) && rootsEqual(s);		
	}
}
