/*******************************************************************************
 * Copyright (c) 2006 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.ui.mappings;

import java.util.*;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.diff.provider.DiffTree;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.mapping.CVSCheckedInChangeSet;
import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.team.internal.ccvs.ui.operations.RemoteLogOperation.LogEntryCache;
import org.eclipse.team.internal.ccvs.ui.subscriber.CVSChangeSetCollector;
import org.eclipse.team.internal.ccvs.ui.subscriber.LogEntryCacheUpdateHandler;
import org.eclipse.team.internal.ccvs.ui.subscriber.LogEntryCacheUpdateHandler.ILogsFetchedListener;
import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;
import org.eclipse.team.internal.core.subscribers.*;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.SynchronizePageActionGroup;

public class CheckedInChangeSetCollector extends BatchingChangeSetManager implements ILogsFetchedListener {

	/*
	 * Constant used to store the log entry handler in the configuration so it can
	 * be kept around over layout changes
	 */
	private static final String LOG_ENTRY_HANDLER = CVSUIPlugin.ID + ".LogEntryHandler"; //$NON-NLS-1$
	
	/* *****************************************************************************
	 * Special sync info that has its kind already calculated.
	 */
	private class CVSUpdatableSyncInfo extends CVSSyncInfo {
		public int kind;
		public CVSUpdatableSyncInfo(int kind, IResource local, IResourceVariant base, IResourceVariant remote, Subscriber s) {
			super(local, base, remote, s);
			this.kind = kind;
		}

		@Override
		protected int calculateKind() throws TeamException {
			return kind;
		}
	}
	
	IDiffChangeListener diffTreeListener = new IDiffChangeListener() {
		@Override
		public void propertyChanged(IDiffTree tree, int property, IPath[] paths) {
			// Ignore
		}
		@Override
		public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) {
			if (event.getTree().isEmpty()) {
				ChangeSet changeSet = getChangeSet(event.getTree());
				if (changeSet != null) {
					remove(changeSet);
				}
			} else {
				ChangeSet changeSet = getChangeSet(event.getTree());
				if (changeSet != null) {
					fireResourcesChangedEvent(changeSet, getAffectedPaths(event));
				}
			}
		}
		private IPath[] getAffectedPaths(IDiffChangeEvent event) {
			Set<IPath> result = new HashSet<>();
			IPath[] removed = event.getRemovals();
			for (int i = 0; i < removed.length; i++) {
				IPath path = removed[i];
				result.add(path);
			}
			IDiff[] diffs = event.getAdditions();
			for (int j = 0; j < diffs.length; j++) {
				IDiff diff = diffs[j];
				result.add(diff.getPath());
			}
			diffs = event.getChanges();
			for (int j = 0; j < diffs.length; j++) {
				IDiff diff = diffs[j];
				result.add(diff.getPath());
			}
			return result.toArray(new IPath[result.size()]);
		}
	};

	private final ISynchronizePageConfiguration configuration;
	private boolean disposed;
	private LogEntryCache logEntryCache;
	private final Subscriber subscriber;

	private HashSet<ChangeSet> updatedSets;
	
	public CheckedInChangeSetCollector(ISynchronizePageConfiguration configuration, Subscriber subscriber) {
		this.configuration = configuration;
		this.subscriber = subscriber;
	}
	
	/**
	 * Return the configuration for the page that is displaying the model created 
	 * using this collector.
	 * @return the configuration for the page that is displaying the model created 
	 * using this collector
	 */
	public final ISynchronizePageConfiguration getConfiguration() {
		return configuration;
	}
	
	@Override
	protected void handleSetAdded(ChangeSet set) {
		((DiffChangeSet)set).getDiffTree().addDiffChangeListener(diffTreeListener);
		super.handleSetAdded(set);
		if (updatedSets != null) {
			updatedSets.add(set);
			((DiffTree)((DiffChangeSet)set).getDiffTree()).beginInput();
		}
	}
	
	@Override
	protected void handleSetRemoved(ChangeSet set) {
		((DiffChangeSet)set).getDiffTree().removeDiffChangeListener(diffTreeListener);
		super.handleSetRemoved(set);
	}
	
	protected ChangeSet getChangeSet(IDiffTree tree) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet changeSet = sets[i];
			if (((DiffChangeSet)changeSet).getDiffTree() == tree) {
				return changeSet;
			}
		}
		return null;
	}
	
	public void handleChange(IDiffChangeEvent event) {
		List<IPath> removals = new ArrayList<>();
		List<IDiff> additions = new ArrayList<>();
		removals.addAll(Arrays.asList(event.getRemovals()));
		additions.addAll(Arrays.asList(event.getAdditions()));
		IDiff[] changed = event.getChanges();
		for (int i = 0; i < changed.length; i++) {
			IDiff diff = changed[i];
			additions.add(diff);
			removals.add(diff.getPath());
		}
		if (!removals.isEmpty()) {
			remove(removals.toArray(new IPath[removals.size()]));
		}
		if (!additions.isEmpty()) {
			add(additions.toArray(new IDiff[additions.size()]));
		}
	}
	
	protected void remove(IPath[] paths) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			DiffChangeSet set = (DiffChangeSet)sets[i];
			set.remove(paths);
		}
	}
	
	public synchronized LogEntryCacheUpdateHandler getLogEntryHandler() {
		LogEntryCacheUpdateHandler handler = (LogEntryCacheUpdateHandler)getConfiguration().getProperty(LOG_ENTRY_HANDLER);
		if (handler == null) {
			handler = initializeLogEntryHandler(getConfiguration());
		}
		handler.setListener(this);
		return handler;
	}
	
	/*
	 * Initialize the log entry handler and place it in the configuration
	 */
	private LogEntryCacheUpdateHandler initializeLogEntryHandler(final ISynchronizePageConfiguration configuration) {
		final LogEntryCacheUpdateHandler logEntryHandler = new LogEntryCacheUpdateHandler(configuration);
		configuration.setProperty(LOG_ENTRY_HANDLER, logEntryHandler);
		// Use an action group to get notified when the configuration is disposed
		configuration.addActionContribution(new SynchronizePageActionGroup() {
			@Override
			public void dispose() {
				super.dispose();
				LogEntryCacheUpdateHandler handler = (LogEntryCacheUpdateHandler)configuration.getProperty(LOG_ENTRY_HANDLER);
				if (handler != null) {
					handler.shutdown();
					configuration.setProperty(LOG_ENTRY_HANDLER, null);
				}
			}
		});
		return logEntryHandler;
	}

	protected void add(IDiff[] diffs) {
		LogEntryCacheUpdateHandler handler = getLogEntryHandler();
		if (handler != null)
			try {
				handler.fetch(getSyncInfos(diffs));
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
	}
	
	private SyncInfo[] getSyncInfos(IDiff[] diffs) {
		SyncInfoSet set = new SyncInfoSet();
		for (int i = 0; i < diffs.length; i++) {
			IDiff diff = diffs[i];
			set.add(getConverter().asSyncInfo(diff, getSubscriber().getResourceComparator()));
		}
		return set.getSyncInfos();
	}

	public Subscriber getSubscriber() {
		return subscriber;
	}

	@Override
	public void dispose() {
		// No longer listen for log entry changes
		// (The handler is disposed with the page)
		disposed = true;
		LogEntryCacheUpdateHandler handler = getLogEntryHandler();
		if (handler != null) handler.setListener(null);
		getConfiguration().setProperty(CVSChangeSetCollector.CVS_CHECKED_IN_COLLECTOR, null);
		logEntryCache = null;
		super.dispose();
	}
	
	/**
	 * Fetch the log histories for the remote changes and use this information
	 * to add each resource to an appropriate commit set.
	 */
	private void handleRemoteChanges(final SyncInfo[] infos, final LogEntryCache logEntries, final IProgressMonitor monitor) {
		try {
			beginSetUpdate();
			addLogEntries(infos, logEntries, monitor);
		} finally {
			endSetUpdate(monitor);
		}
	}
	
	private void beginSetUpdate() {
		updatedSets = new HashSet<>();
	}

	private void endSetUpdate(IProgressMonitor monitor) {
		for (Iterator iter = updatedSets.iterator(); iter.hasNext();) {
			DiffChangeSet set = (DiffChangeSet) iter.next();
			try {
				((DiffTree)set.getDiffTree()).endInput(monitor);
			} catch (RuntimeException e) {
				CVSUIPlugin.log(IStatus.ERROR, "Internal error", e); //$NON-NLS-1$
			}
		}
		updatedSets = null;
	}

	/*
	 * Add the following sync info elements to the viewer. It is assumed that these elements have associated
	 * log entries cached in the log operation.
	 */
	private void addLogEntries(SyncInfo[] commentInfos, LogEntryCache logs, IProgressMonitor monitor) {
		try {
			monitor.beginTask(null, commentInfos.length * 10);
			if (logs != null) {
				for (int i = 0; i < commentInfos.length; i++) {
					addSyncInfoToCommentNode(commentInfos[i], logs);
					monitor.worked(10);
				}
			}
		} finally {
			monitor.done();
		}
	}
	
	/*
	 * Create a node for the given sync info object. The logs should contain the log for this info.
	 * 
	 * @param info the info for which to create a node in the model
	 * @param log the cvs log for this node
	 */
	private void addSyncInfoToCommentNode(SyncInfo info, LogEntryCache logs) {
		LogEntryCacheUpdateHandler handler = getLogEntryHandler();
		if (handler != null) {
			ICVSRemoteResource remoteResource = handler.getRemoteResource(info);
			if(handler.getSubscriber() instanceof CVSCompareSubscriber && remoteResource != null) {
				addMultipleRevisions(info, logs, remoteResource);
			} else {
				addSingleRevision(info, logs, remoteResource);
			}
		}
	}
	
	/*
	 * Add a single log entry to the model.
	 * 
	 * @param info
	 * @param logs
	 * @param remoteResource
	 */
	private void addSingleRevision(SyncInfo info, LogEntryCache logs, ICVSRemoteResource remoteResource) {
		ILogEntry logEntry = logs.getLogEntry(remoteResource);
		if (remoteResource != null && !remoteResource.isFolder()) {
			// For incoming deletions grab the comment for the latest on the same branch
			// which is now in the attic.
			try {
				String remoteRevision = ((ICVSRemoteFile) remoteResource).getRevision();
				if (isDeletedRemotely(info)) {
					ILogEntry[] logEntries = logs.getLogEntries(remoteResource);
					for (int i = 0; i < logEntries.length; i++) {
						ILogEntry entry = logEntries[i];
						String revision = entry.getRevision();
						if (entry.isDeletion() && ResourceSyncInfo.isLaterRevision(revision, remoteRevision)) {
							logEntry = entry;
						}
					}
				}
			} catch (TeamException e) {
				// continue and skip deletion checks
			}
		}
		addRemoteChange(info, remoteResource, logEntry);
	}
	
	/*
	 * Add multiple log entries to the model.
	 * 
	 * @param info
	 * @param logs
	 * @param remoteResource
	 */
	private void addMultipleRevisions(SyncInfo info, LogEntryCache logs, ICVSRemoteResource remoteResource) {
		ILogEntry[] logEntries = logs.getLogEntries(remoteResource);
		if(logEntries == null || logEntries.length == 0) {
			// If for some reason we don't have a log entry, try the latest
			// remote.
			addRemoteChange(info, null, null);
		} else {
			for (int i = 0; i < logEntries.length; i++) {
				ILogEntry entry = logEntries[i];
				addRemoteChange(info, remoteResource, entry);
			}
		}
	}
	
	private boolean isDeletedRemotely(SyncInfo info) {
		int kind = info.getKind();
		if(kind == (SyncInfo.INCOMING | SyncInfo.DELETION)) return true;
		if(SyncInfo.getDirection(kind) == SyncInfo.CONFLICTING && info.getRemote() == null) return true;
		return false;
	}
	
	/*
	 * Add the remote change to an incoming commit set
	 */
	private void addRemoteChange(SyncInfo info, ICVSRemoteResource remoteResource, ILogEntry logEntry) {
		if (disposed) return;
		LogEntryCacheUpdateHandler handler = getLogEntryHandler();
		if(handler != null && remoteResource != null && logEntry != null && handler.isRemoteChange(info)) {
			if(requiresCustomSyncInfo(info, remoteResource, logEntry)) {
				info = new CVSUpdatableSyncInfo(info.getKind(), info.getLocal(), info.getBase(), (RemoteResource)logEntry.getRemoteFile(), getSubscriber());
				try {
					info.init();
				} catch (TeamException e) {
					// this shouldn't happen, we've provided our own calculate kind
				}
			}
			IDiff diff = getConverter().getDeltaFor(info);
			// Only add the info if the base and remote differ
			IResourceVariant base = info.getBase();
			IResourceVariant remote = info.getRemote();
			if ((base == null && remote != null) || (remote == null && base != null) || (remote != null && base != null && !base.equals(remote))) {
				synchronized(this) {
					CVSCheckedInChangeSet set = getChangeSetFor(logEntry);
					if (set == null) {
						set = createChangeSetFor(logEntry);
						add(set);
					}
					set.add(diff);
				}
			}
		} else {
			// The info was not retrieved for the remote change for some reason.
			// Add the node to the root
			//addToDefaultSet(DEFAULT_INCOMING_SET_NAME, info);
		}
	}

	private SyncInfoToDiffConverter getConverter() {
		SyncInfoToDiffConverter converter = Adapters.adapt(subscriber, SyncInfoToDiffConverter.class);
		if (converter == null)
			converter = SyncInfoToDiffConverter.getDefault();
		return converter;
	}

	private CVSCheckedInChangeSet createChangeSetFor(ILogEntry logEntry) {
		return new CVSCheckedInChangeSet(logEntry);
	}

	private CVSCheckedInChangeSet getChangeSetFor(ILogEntry logEntry) {
		ChangeSet[] sets = getSets();
		for (int i = 0; i < sets.length; i++) {
			ChangeSet set = sets[i];
			if (set instanceof CVSCheckedInChangeSet &&
					set.getComment().equals(logEntry.getComment()) &&
					((CVSCheckedInChangeSet)set).getAuthor().equals(logEntry.getAuthor())) {
				return (CVSCheckedInChangeSet)set;
			}
		}
		return null;
	}
	
	private boolean requiresCustomSyncInfo(SyncInfo info, ICVSRemoteResource remoteResource, ILogEntry logEntry) {
		// Only interested in non-deletions
		if (logEntry.isDeletion()) return false;
		// Only require a custom sync info if the remote of the sync info
		// differs from the remote in the log entry
		IResourceVariant remote = info.getRemote();
		if (remote == null) return true;
		return !remote.equals(remoteResource);
	}
	
	/*
	 * @see
	 * org.eclipse.team.ui.synchronize.SyncInfoSetChangeSetCollector#waitUntilDone(
	 * org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void waitUntilDone(IProgressMonitor monitor) {
		monitor.worked(1);
		// wait for the event handler to process changes.
		LogEntryCacheUpdateHandler handler = getLogEntryHandler();
		if (handler != null) {
			while(handler.getEventHandlerJob().getState() != Job.NONE) {
				monitor.worked(1);
				try {
					Thread.sleep(10);		
				} catch (InterruptedException e) {
				}
				Policy.checkCanceled(monitor);
			}
		}
		monitor.worked(1);
	}

	@Override
	public void logEntriesFetched(SyncInfoSet set, LogEntryCache logEntryCache, IProgressMonitor monitor) {
		if (disposed) return;
		// Hold on to the cache so we can use it while commit sets are visible
		this.logEntryCache = logEntryCache;
		try {
			beginInput();
			handleRemoteChanges(set.getSyncInfos(), logEntryCache, monitor);
		} finally {
			endInput(monitor);
		}
	}

	public ICVSRemoteFile getImmediatePredecessor(ICVSRemoteFile file) throws TeamException {
		if (logEntryCache != null)
			return logEntryCache.getImmediatePredecessor(file);
		return null;
	}
}
