/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *     Matt McCutchen <hashproduct+eclipse@gmail.com> - Bug 179174 CVS client sets timestamps back when replacing
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.operations;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.*;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.PrepareForReplaceVisitor;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.team.internal.ccvs.ui.tags.TagSource;
import org.eclipse.team.internal.ccvs.ui.tags.TagSourceWorkbenchAdapter;
import org.eclipse.ui.IWorkbenchPart;

/**
 * This operation replaces the local resources with their remote contents
 */
public class ReplaceOperation extends UpdateOperation {

	public ReplaceOperation(IWorkbenchPart part, IResource[] resources, CVSTag tag, boolean recurse) {
		super(part, asResourceMappers(resources, recurse ? IResource.DEPTH_INFINITE : IResource.DEPTH_ONE), new LocalOption[] { Update.IGNORE_LOCAL_CHANGES }, tag);
	}

	public ReplaceOperation(IWorkbenchPart part, ResourceMapping[] mappings, CVSTag tag) {
		super(part, mappings, new LocalOption[] { Update.IGNORE_LOCAL_CHANGES }, tag);
	}

	@Override
	protected String getTaskName() {
		return CVSUIMessages.ReplaceOperation_taskName; 
	}

	@Override
	protected IStatus executeCommand(
		final Session session,
		final CVSTeamProvider provider,
		final ICVSResource[] resources,
		final boolean recurse, IProgressMonitor monitor)
		throws CVSException, InterruptedException {
		
		final IStatus[] status = new IStatus[] { Status.OK_STATUS };
		try {
			ResourcesPlugin.getWorkspace().run((IWorkspaceRunnable) monitor1 -> {
				try {
					status[0] = internalExecuteCommand(session, provider, resources, recurse, monitor1);
				} catch (InterruptedException e) {
					throw new OperationCanceledException();
				}
			}, null, IWorkspace.AVOID_UPDATE, monitor);
		} catch (CoreException e) {
			throw CVSException.wrapException(e);
		}
		return status[0];
	}

	// Files deleted by the PrepareForReplaceVisitor.
	private Set/*<ICVSFile>*/ prepDeletedFiles;

	/**
	 * Tells whether resources for which the given tag does not exists, are ignored by the replace
	 * operation.
	 */
	private boolean ignoreResourcesIfTagDoesNotExist;


	private IStatus internalExecuteCommand(Session session, CVSTeamProvider provider, ICVSResource[] resources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException {
		monitor.beginTask(null, 100);
		ICVSResource[] managedResources = getResourcesToUpdate(resources, Policy.subMonitorFor(monitor, 5));
		if (ignoreResourcesIfTagDoesNotExist && managedResources.length == 0)
			return OK;

		try {
			// Purge any unmanaged or added files
			PrepareForReplaceVisitor pfrv = new PrepareForReplaceVisitor(session, getTag());
			pfrv.visitResources(
				provider.getProject(), 
				resources, 
				CVSUIMessages.ReplaceOperation_1, 
				recurse ? IResource.DEPTH_INFINITE : IResource.DEPTH_ONE, 
				Policy.subMonitorFor(monitor, 25));
			prepDeletedFiles = pfrv.getDeletedFiles();
			
			// Only perform the remote command if some of the resources being replaced were managed
			IStatus status = OK;
			if (managedResources.length > 0) {
				// Perform an update, ignoring any local file modifications
				status = super.executeCommand(session, provider, managedResources, recurse, Policy.subMonitorFor(monitor, 70));
			}
			
			// Prune any empty folders left after the resources were purged.
			// This is done to prune any empty folders that contained only unmanaged resources
			if (status.isOK() && CVSProviderPlugin.getPlugin().getPruneEmptyDirectories()) {
				new PruneFolderVisitor().visit(session, resources);
			}
			
			return status;
		} finally {
			monitor.done();
		}
	}

	/**
	 * Return the resources that need to be updated from the server.
	 * By default, this is all resources that are managed.
	 * @param resources all resources being replaced
	 * @return resources that are to be updated from the server
	 * @throws CVSException
	 */
	protected ICVSResource[] getResourcesToUpdate(ICVSResource[] resources, IProgressMonitor monitor) throws CVSException {
		// Accumulate the managed resources from the list of provided resources
		List<ICVSResource> managedResources = new ArrayList<>();
		monitor.beginTask(null, resources.length * 100);
		for (int i = 0; i < resources.length; i++) {
			ICVSResource resource = resources[i];
			if ((resource.isFolder() && ((ICVSFolder)resource).isCVSFolder())) {
				addResourceIfTagExists(managedResources, resource, Policy.subMonitorFor(monitor, 100));
			} else if (!resource.isFolder()){
				byte[] syncBytes = ((ICVSFile)resource).getSyncBytes();
				if (syncBytes != null && !ResourceSyncInfo.isAddition(syncBytes)) {
					addResourceIfTagExists(managedResources, resource, Policy.subMonitorFor(monitor, 100));
				}
			}
		}
		monitor.done();
		return managedResources.toArray(new ICVSResource[managedResources.size()]);
	}

	private void addResourceIfTagExists(List<ICVSResource> managedResources, ICVSResource resource,
			IProgressMonitor monitor) {
		CVSTag tag = getTag();
		if (tag == null || tag.getType() == CVSTag.DATE || tag.isHeadTag() || tag.isBaseTag()) {
			// No need to check for date, head or base tags
			managedResources.add(resource);
		} else {
			TagSource tagSource= TagSource.create(new ICVSResource[] { resource });
			if (isTagPresent(tagSource, tag)) {
				managedResources.add(resource);
			} else {
				// If the tag usn't present, lets refresh just to make sure
				try {
					tagSource.refresh(false, monitor);
					if (isTagPresent(tagSource, tag)) {
						managedResources.add(resource);
					} else {
						tagSource.refresh(true, monitor);
						if (isTagPresent(tagSource, tag)) {
							managedResources.add(resource);
						}
					}
				} catch (TeamException e) {
					CVSUIPlugin.log(e);
				}
			}
		}
	}
	
	private boolean isTagPresent(TagSource tagSource, CVSTag tag) {
		CVSTag[] tags= tagSource.getTags(TagSource.convertIncludeFlaqsToTagTypes(TagSourceWorkbenchAdapter.INCLUDE_ALL_TAGS));
		return Arrays.asList(tags).contains(tag);
	}
	
	@Override
	protected Update getUpdateCommand() {
		// Use a special replace command that doesn't set back the timestamps
		// of files in the passed set if it recreates them.
		return new Replace(prepDeletedFiles);
	}

	@Override
	protected String getTaskName(CVSTeamProvider provider) {
		return NLS.bind(CVSUIMessages.ReplaceOperation_0, new String[] { provider.getProject().getName() }); 
	}

	/**
	 * Tells to ignore resources for which the given tag does not exists.
	 */
	public void ignoreResourcesWithMissingTag() {
		ignoreResourcesIfTagDoesNotExist= true;
	}
}
