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


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
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.client.listeners.ICommandOutputListener;
import org.eclipse.team.internal.ccvs.core.client.listeners.UpdateListener;

public class Update extends Command {
	/*** Local options: specific to update ***/
	public static final LocalOption CLEAR_STICKY = new LocalOption("-A"); //$NON-NLS-1$
	public static final LocalOption IGNORE_LOCAL_CHANGES = new LocalOption("-C"); //$NON-NLS-1$
	public static final LocalOption RETRIEVE_ABSENT_DIRECTORIES = new LocalOption("-d"); //$NON-NLS-1$
	public static final LocalOption JOIN = new LocalOption("-j"); //$NON-NLS-1$
	
	/*** Default command output listener ***/
	private static final ICommandOutputListener DEFAULT_OUTPUT_LISTENER = new UpdateListener(null);
	
	/*** File information status returned from update ***/
	public static final int STATE_NONE = 0;							// no state information available
	public static final int STATE_ADDED_LOCAL = 1; 			// new file locally that was added but not comitted to server yet
	public static final int STATE_UNKOWN = 2; 						// new file locally but not added to server
	public static final int STATE_REMOTE_CHANGES = 3; 		// remote changes to an unmodified local file
	public static final int STATE_DELETED = 4; 						// removed locally but still exists on the server
	public static final int STATE_MODIFIED = 5; 					// modified locally
	public static final int STATE_CONFLICT = 6; 					// modified locally and on the server but cannot be auto-merged
	public static final int STATE_MERGEABLE_CONFLICT = 7;  // modified locally and on the server but can be auto-merged

	/**
	 * Makes a -r or -D or -A option for a tag.
	 * Valid for: checkout export history rdiff update
	 */
	public static LocalOption makeTagOption(CVSTag tag) {
		int type = tag.getType();
		switch (type) {
			case CVSTag.HEAD:
				return CLEAR_STICKY;
			default:
				return Command.makeTagOption(tag);
		}
	}
	
	protected Update() { }
	protected String getRequestId() {
		return "update"; //$NON-NLS-1$
	}
	
	protected ICommandOutputListener getDefaultCommandOutputListener() {
		return DEFAULT_OUTPUT_LISTENER;
	}
	
	protected ICVSResource[] sendLocalResourceState(Session session, GlobalOption[] globalOptions,
		LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor)
		throws CVSException {			
		
		// Send all folders that are already managed to the server
		// even folders that are empty
		sendFileStructure(session, resources, localOptions, true, monitor);
		return resources;
	}
	
	/**
	 * On successful finish, prune empty directories if the -P or -D option was specified.
	 */
	protected IStatus commandFinished(Session session, GlobalOption[] globalOptions,
		LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor,
		IStatus status) throws CVSException {
		// If we didn't succeed, don't do any post processing
		if (status.getCode() == CVSStatus.SERVER_ERROR) {
			return status;
		}

		// If we are pruning (-P), then prune empty directories
		// Note, the CVS spec says that Date (-D) and version (-r) updates
		// should automatically prune but this is a problem for remote CVS handles
		// which fetch a level at a time
		if (PRUNE_EMPTY_DIRECTORIES.isElementOf(localOptions)) { 
			// Delete empty directories
			new PruneFolderVisitor().visit(session, resources);
			
		}
		return status;
	}
	
	protected LocalOption[] filterLocalOptions(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions) {
		List<LocalOption> newOptions = new ArrayList<>(Arrays.asList(localOptions));
		
		if (shouldRetrieveAbsentDirectories(session) && ! RETRIEVE_ABSENT_DIRECTORIES.isElementOf(localOptions)) {
			newOptions.add(Update.RETRIEVE_ABSENT_DIRECTORIES);
		}

		// Prune empty directories if pruning is enabled and the command in not being run in non-update mode
		if (CVSProviderPlugin.getPlugin().getPruneEmptyDirectories() && ! PRUNE_EMPTY_DIRECTORIES.isElementOf(localOptions)) {
			if (! DO_NOT_CHANGE.isElementOf(globalOptions)) {
				newOptions.add(Command.PRUNE_EMPTY_DIRECTORIES);
			}
		}
		localOptions = (LocalOption[]) newOptions.toArray(new LocalOption[newOptions.size()]);
		return super.filterLocalOptions(session, globalOptions, localOptions);
	}
	
	/**
	 * Return whether the update command should retrieve absent directories.
	 * @param session the session
	 * @return whether the update command should retrieve absent directories
	 */
	protected boolean shouldRetrieveAbsentDirectories(Session session) {
		// Look for absent directories if enabled and the option is not already included
		IResource resource = null;
		RepositoryProvider provider = null;
		// If there is a provider, use the providers setting
		try {
			resource = session.getLocalRoot().getIResource();
			if (resource != null) {
				provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId());
				if (provider != null) {
					if (((CVSTeamProvider)provider).getFetchAbsentDirectories()) {
						return true;
					}
				}
			}
		} catch (CVSException e) {
			CVSProviderPlugin.log(e);
		}
		// If there is no provider, use the global setting
		if (provider == null) {
			if (CVSProviderPlugin.getPlugin().getFetchAbsentDirectories()) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * We allow unmanaged resources as long as there parents are managed.
	 * 
	 * @see Command#checkResourcesManaged(Session, ICVSResource[])
	 */
	protected void checkResourcesManaged(Session session, ICVSResource[] resources) throws CVSException {
		for (int i = 0; i < resources.length; ++i) {
			ICVSFolder folder;
			if (resources[i].isFolder()) {
				if (((ICVSFolder)resources[i]).isCVSFolder()) {
					folder = (ICVSFolder)resources[i];
				} else {
					folder = resources[i].getParent();
				}
			}
			else {
				folder = resources[i].getParent();
			}
			if (folder==null || (!folder.isCVSFolder() && folder.exists())) {
                if (folder == null)
                    folder = (ICVSFolder)resources[i];
                IStatus status = new CVSStatus(IStatus.ERROR,CVSStatus.ERROR,NLS.bind(CVSMessages.Command_argumentNotManaged, new String[] { folder.getName() }),session.getLocalRoot());
				throw new CVSException(status);
			}
		}
	}

	@Override
	protected IStatus doExecute(
			Session session,
			GlobalOption[] globalOptions,
			LocalOption[] localOptions,
			String[] arguments,
			ICommandOutputListener listener,
			IProgressMonitor monitor)
			throws CVSException {
			
		session.setIgnoringLocalChanges(IGNORE_LOCAL_CHANGES.isElementOf(localOptions));
		try {
			return super.doExecute(
				session,
				globalOptions,
				localOptions,
				arguments,
				listener,
				monitor);
		} finally {
			session.setIgnoringLocalChanges(false);
		}

	}

}
