/*
 * Copyright (C) 2008, Google Inc.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.transport;

import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * A command being processed by
 * {@link org.eclipse.jgit.transport.BaseReceivePack}.
 * <p>
 * This command instance roughly translates to the server side representation of
 * the {@link org.eclipse.jgit.transport.RemoteRefUpdate} created by the client.
 */
public class ReceiveCommand {
	/** Type of operation requested. */
	public static enum Type {
		/** Create a new ref; the ref must not already exist. */
		CREATE,

		/**
		 * Update an existing ref with a fast-forward update.
		 * <p>
		 * During a fast-forward update no changes will be lost; only new
		 * commits are inserted into the ref.
		 */
		UPDATE,

		/**
		 * Update an existing ref by potentially discarding objects.
		 * <p>
		 * The current value of the ref is not fully reachable from the new
		 * value of the ref, so a successful command may result in one or more
		 * objects becoming unreachable.
		 */
		UPDATE_NONFASTFORWARD,

		/** Delete an existing ref; the ref should already exist. */
		DELETE;
	}

	/** Result of the update command. */
	public static enum Result {
		/** The command has not yet been attempted by the server. */
		NOT_ATTEMPTED,

		/** The server is configured to deny creation of this ref. */
		REJECTED_NOCREATE,

		/** The server is configured to deny deletion of this ref. */
		REJECTED_NODELETE,

		/** The update is a non-fast-forward update and isn't permitted. */
		REJECTED_NONFASTFORWARD,

		/** The update affects <code>HEAD</code> and cannot be permitted. */
		REJECTED_CURRENT_BRANCH,

		/**
		 * One or more objects aren't in the repository.
		 * <p>
		 * This is severe indication of either repository corruption on the
		 * server side, or a bug in the client wherein the client did not supply
		 * all required objects during the pack transfer.
		 */
		REJECTED_MISSING_OBJECT,

		/** Other failure; see {@link ReceiveCommand#getMessage()}. */
		REJECTED_OTHER_REASON,

		/** The ref could not be locked and updated atomically; try again. */
		LOCK_FAILURE,

		/** The change was completed successfully. */
		OK;
	}

	/**
	 * Filter a collection of commands according to result.
	 *
	 * @param in
	 *            commands to filter.
	 * @param want
	 *            desired status to filter by.
	 * @return a copy of the command list containing only those commands with
	 *         the desired status.
	 * @since 4.2
	 */
	public static List<ReceiveCommand> filter(Iterable<ReceiveCommand> in,
			Result want) {
		List<ReceiveCommand> r;
		if (in instanceof Collection)
			r = new ArrayList<>(((Collection<?>) in).size());
		else
			r = new ArrayList<>();
		for (ReceiveCommand cmd : in) {
			if (cmd.getResult() == want)
				r.add(cmd);
		}
		return r;
	}

	/**
	 * Filter a list of commands according to result.
	 *
	 * @param commands
	 *            commands to filter.
	 * @param want
	 *            desired status to filter by.
	 * @return a copy of the command list containing only those commands with
	 *         the desired status.
	 * @since 2.0
	 */
	public static List<ReceiveCommand> filter(List<ReceiveCommand> commands,
			Result want) {
		return filter((Iterable<ReceiveCommand>) commands, want);
	}

	/**
	 * Set unprocessed commands as failed due to transaction aborted.
	 * <p>
	 * If a command is still
	 * {@link org.eclipse.jgit.transport.ReceiveCommand.Result#NOT_ATTEMPTED} it
	 * will be set to
	 * {@link org.eclipse.jgit.transport.ReceiveCommand.Result#REJECTED_OTHER_REASON}.
	 *
	 * @param commands
	 *            commands to mark as failed.
	 * @since 4.2
	 */
	public static void abort(Iterable<ReceiveCommand> commands) {
		for (ReceiveCommand c : commands) {
			if (c.getResult() == NOT_ATTEMPTED) {
				c.setResult(REJECTED_OTHER_REASON,
						JGitText.get().transactionAborted);
			}
		}
	}

	/**
	 * Check whether a command failed due to transaction aborted.
	 *
	 * @param cmd
	 *            command.
	 * @return whether the command failed due to transaction aborted, as in
	 *         {@link #abort(Iterable)}.
	 * @since 4.9
	 */
	public static boolean isTransactionAborted(ReceiveCommand cmd) {
		return cmd.getResult() == REJECTED_OTHER_REASON
				&& cmd.getMessage().equals(JGitText.get().transactionAborted);
	}

	/**
	 * Create a command to switch a reference from object to symbolic.
	 *
	 * @param oldId
	 *            expected oldId. May be {@code zeroId} to create.
	 * @param newTarget
	 *            new target; must begin with {@code "refs/"}.
	 * @param name
	 *            name of the reference to make symbolic.
	 * @return command instance.
	 * @since 4.10
	 */
	public static ReceiveCommand link(@NonNull ObjectId oldId,
			@NonNull String newTarget, @NonNull String name) {
		return new ReceiveCommand(oldId, newTarget, name);
	}

	/**
	 * Create a command to switch a symbolic reference's target.
	 *
	 * @param oldTarget
	 *            expected old target. May be null to create.
	 * @param newTarget
	 *            new target; must begin with {@code "refs/"}.
	 * @param name
	 *            name of the reference to make symbolic.
	 * @return command instance.
	 * @since 4.10
	 */
	public static ReceiveCommand link(@Nullable String oldTarget,
			@NonNull String newTarget, @NonNull String name) {
		return new ReceiveCommand(oldTarget, newTarget, name);
	}

	/**
	 * Create a command to switch a reference from symbolic to object.
	 *
	 * @param oldTarget
	 *            expected old target.
	 * @param newId
	 *            new object identifier. May be {@code zeroId()} to delete.
	 * @param name
	 *            name of the reference to convert from symbolic.
	 * @return command instance.
	 * @since 4.10
	 */
	public static ReceiveCommand unlink(@NonNull String oldTarget,
			@NonNull ObjectId newId, @NonNull String name) {
		return new ReceiveCommand(oldTarget, newId, name);
	}

	private final ObjectId oldId;

	private final String oldSymref;

	private final ObjectId newId;

	private final String newSymref;

	private final String name;

	private Type type;

	private boolean typeIsCorrect;

	private Ref ref;

	private Result status = Result.NOT_ATTEMPTED;

	private String message;

	private boolean customRefLog;

	private String refLogMessage;

	private boolean refLogIncludeResult;

	private Boolean forceRefLog;

	/**
	 * Create a new command for
	 * {@link org.eclipse.jgit.transport.BaseReceivePack}.
	 *
	 * @param oldId
	 *            the expected old object id; must not be null. Use
	 *            {@link org.eclipse.jgit.lib.ObjectId#zeroId()} to indicate a
	 *            ref creation.
	 * @param newId
	 *            the new object id; must not be null. Use
	 *            {@link org.eclipse.jgit.lib.ObjectId#zeroId()} to indicate a
	 *            ref deletion.
	 * @param name
	 *            name of the ref being affected.
	 */
	public ReceiveCommand(final ObjectId oldId, final ObjectId newId,
			final String name) {
		if (oldId == null) {
			throw new IllegalArgumentException(
					JGitText.get().oldIdMustNotBeNull);
		}
		if (newId == null) {
			throw new IllegalArgumentException(
					JGitText.get().newIdMustNotBeNull);
		}
		if (name == null || name.isEmpty()) {
			throw new IllegalArgumentException(
					JGitText.get().nameMustNotBeNullOrEmpty);
		}
		this.oldId = oldId;
		this.oldSymref = null;
		this.newId = newId;
		this.newSymref = null;
		this.name = name;

		type = Type.UPDATE;
		if (ObjectId.zeroId().equals(oldId)) {
			type = Type.CREATE;
		}
		if (ObjectId.zeroId().equals(newId)) {
			type = Type.DELETE;
		}
	}

	/**
	 * Create a new command for
	 * {@link org.eclipse.jgit.transport.BaseReceivePack}.
	 *
	 * @param oldId
	 *            the old object id; must not be null. Use
	 *            {@link org.eclipse.jgit.lib.ObjectId#zeroId()} to indicate a
	 *            ref creation.
	 * @param newId
	 *            the new object id; must not be null. Use
	 *            {@link org.eclipse.jgit.lib.ObjectId#zeroId()} to indicate a
	 *            ref deletion.
	 * @param name
	 *            name of the ref being affected.
	 * @param type
	 *            type of the command. Must be
	 *            {@link org.eclipse.jgit.transport.ReceiveCommand.Type#CREATE}
	 *            if {@code
	 *            oldId} is zero, or
	 *            {@link org.eclipse.jgit.transport.ReceiveCommand.Type#DELETE}
	 *            if {@code newId} is zero.
	 * @since 2.0
	 */
	public ReceiveCommand(final ObjectId oldId, final ObjectId newId,
			final String name, final Type type) {
		if (oldId == null) {
			throw new IllegalArgumentException(
					JGitText.get().oldIdMustNotBeNull);
		}
		if (newId == null) {
			throw new IllegalArgumentException(
					JGitText.get().newIdMustNotBeNull);
		}
		if (name == null || name.isEmpty()) {
			throw new IllegalArgumentException(
					JGitText.get().nameMustNotBeNullOrEmpty);
		}
		this.oldId = oldId;
		this.oldSymref = null;
		this.newId = newId;
		this.newSymref = null;
		this.name = name;
		switch (type) {
		case CREATE:
			if (!ObjectId.zeroId().equals(oldId)) {
				throw new IllegalArgumentException(
						JGitText.get().createRequiresZeroOldId);
			}
			break;
		case DELETE:
			if (!ObjectId.zeroId().equals(newId)) {
				throw new IllegalArgumentException(
						JGitText.get().deleteRequiresZeroNewId);
			}
			break;
		case UPDATE:
		case UPDATE_NONFASTFORWARD:
			if (ObjectId.zeroId().equals(newId)
					|| ObjectId.zeroId().equals(oldId)) {
				throw new IllegalArgumentException(
						JGitText.get().updateRequiresOldIdAndNewId);
			}
			break;
		default:
			throw new IllegalStateException(
					JGitText.get().enumValueNotSupported0);
		}
		this.type = type;
	}

	/**
	 * Create a command to switch a reference from object to symbolic.
	 *
	 * @param oldId
	 *            the old object id; must not be null. Use
	 *            {@link ObjectId#zeroId()} to indicate a ref creation.
	 * @param newSymref
	 *            new target, must begin with {@code "refs/"}. Use {@code null}
	 *            to indicate a ref deletion.
	 * @param name
	 *            name of the reference to make symbolic.
	 * @since 4.10
	 */
	private ReceiveCommand(ObjectId oldId, String newSymref, String name) {
		if (oldId == null) {
			throw new IllegalArgumentException(
					JGitText.get().oldIdMustNotBeNull);
		}
		if (name == null || name.isEmpty()) {
			throw new IllegalArgumentException(
					JGitText.get().nameMustNotBeNullOrEmpty);
		}
		this.oldId = oldId;
		this.oldSymref = null;
		this.newId = ObjectId.zeroId();
		this.newSymref = newSymref;
		this.name = name;
		if (AnyObjectId.equals(ObjectId.zeroId(), oldId)) {
			type = Type.CREATE;
		} else if (newSymref != null) {
			type = Type.UPDATE;
		} else {
			type = Type.DELETE;
		}
		typeIsCorrect = true;
	}

	/**
	 * Create a command to switch a reference from symbolic to object.
	 *
	 * @param oldSymref
	 *            expected old target. Use {@code null} to indicate a ref
	 *            creation.
	 * @param newId
	 *            the new object id; must not be null. Use
	 *            {@link ObjectId#zeroId()} to indicate a ref deletion.
	 * @param name
	 *            name of the reference to convert from symbolic.
	 * @since 4.10
	 */
	private ReceiveCommand(String oldSymref, ObjectId newId, String name) {
		if (newId == null) {
			throw new IllegalArgumentException(
					JGitText.get().newIdMustNotBeNull);
		}
		if (name == null || name.isEmpty()) {
			throw new IllegalArgumentException(
					JGitText.get().nameMustNotBeNullOrEmpty);
		}
		this.oldId = ObjectId.zeroId();
		this.oldSymref = oldSymref;
		this.newId = newId;
		this.newSymref = null;
		this.name = name;
		if (oldSymref == null) {
			type = Type.CREATE;
		} else if (!AnyObjectId.equals(ObjectId.zeroId(), newId)) {
			type = Type.UPDATE;
		} else {
			type = Type.DELETE;
		}
		typeIsCorrect = true;
	}

	/**
	 * Create a command to switch a symbolic reference's target.
	 *
	 * @param oldTarget
	 *            expected old target. Use {@code null} to indicate a ref
	 *            creation.
	 * @param newTarget
	 *            new target. Use {@code null} to indicate a ref deletion.
	 * @param name
	 *            name of the reference to make symbolic.
	 * @since 4.10
	 */
	private ReceiveCommand(@Nullable String oldTarget, String newTarget, String name) {
		if (name == null || name.isEmpty()) {
			throw new IllegalArgumentException(
					JGitText.get().nameMustNotBeNullOrEmpty);
		}
		this.oldId = ObjectId.zeroId();
		this.oldSymref = oldTarget;
		this.newId = ObjectId.zeroId();
		this.newSymref = newTarget;
		this.name = name;
		if (oldTarget == null) {
			if (newTarget == null) {
				throw new IllegalArgumentException(
						JGitText.get().bothRefTargetsMustNotBeNull);
			}
			type = Type.CREATE;
		} else if (newTarget != null) {
			type = Type.UPDATE;
		} else {
			type = Type.DELETE;
		}
		typeIsCorrect = true;
	}

	/**
	 * Get the old value the client thinks the ref has.
	 *
	 * @return the old value the client thinks the ref has.
	 */
	public ObjectId getOldId() {
		return oldId;
	}

	/**
	 * Get expected old target for a symbolic reference.
	 *
	 * @return expected old target for a symbolic reference.
	 * @since 4.10
	 */
	@Nullable
	public String getOldSymref() {
		return oldSymref;
	}

	/**
	 * Get the requested new value for this ref.
	 *
	 * @return the requested new value for this ref.
	 */
	public ObjectId getNewId() {
		return newId;
	}

	/**
	 * Get requested new target for a symbolic reference.
	 *
	 * @return requested new target for a symbolic reference.
	 * @since 4.10
	 */
	@Nullable
	public String getNewSymref() {
		return newSymref;
	}

	/**
	 * Get the name of the ref being updated.
	 *
	 * @return the name of the ref being updated.
	 */
	public String getRefName() {
		return name;
	}

	/**
	 * Get the type of this command; see {@link Type}.
	 *
	 * @return the type of this command; see {@link Type}.
	 */
	public Type getType() {
		return type;
	}

	/**
	 * Get the ref, if this was advertised by the connection.
	 *
	 * @return the ref, if this was advertised by the connection.
	 */
	public Ref getRef() {
		return ref;
	}

	/**
	 * Get the current status code of this command.
	 *
	 * @return the current status code of this command.
	 */
	public Result getResult() {
		return status;
	}

	/**
	 * Get the message associated with a failure status.
	 *
	 * @return the message associated with a failure status.
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * Set the message to include in the reflog.
	 * <p>
	 * Overrides the default set by {@code setRefLogMessage} on any containing
	 * {@link org.eclipse.jgit.lib.BatchRefUpdate}.
	 *
	 * @param msg
	 *            the message to describe this change. If null and appendStatus is
	 *            false, the reflog will not be updated.
	 * @param appendStatus
	 *            true if the status of the ref change (fast-forward or
	 *            forced-update) should be appended to the user supplied message.
	 * @since 4.9
	 */
	public void setRefLogMessage(String msg, boolean appendStatus) {
		customRefLog = true;
		if (msg == null && !appendStatus) {
			disableRefLog();
		} else if (msg == null && appendStatus) {
			refLogMessage = ""; //$NON-NLS-1$
			refLogIncludeResult = true;
		} else {
			refLogMessage = msg;
			refLogIncludeResult = appendStatus;
		}
	}

	/**
	 * Don't record this update in the ref's associated reflog.
	 * <p>
	 * Equivalent to {@code setRefLogMessage(null, false)}.
	 *
	 * @since 4.9
	 */
	public void disableRefLog() {
		customRefLog = true;
		refLogMessage = null;
		refLogIncludeResult = false;
	}

	/**
	 * Force writing a reflog for the updated ref.
	 *
	 * @param force whether to force.
	 * @since 4.9
	 */
	public void setForceRefLog(boolean force) {
		forceRefLog = Boolean.valueOf(force);
	}

	/**
	 * Check whether this command has a custom reflog message setting that should
	 * override defaults in any containing
	 * {@link org.eclipse.jgit.lib.BatchRefUpdate}.
	 * <p>
	 * Does not take into account whether {@code #setForceRefLog(boolean)} has
	 * been called.
	 *
	 * @return whether a custom reflog is set.
	 * @since 4.9
	 */
	public boolean hasCustomRefLog() {
		return customRefLog;
	}

	/**
	 * Check whether log has been disabled by {@link #disableRefLog()}.
	 *
	 * @return true if disabled.
	 * @since 4.9
	 */
	public boolean isRefLogDisabled() {
		return refLogMessage == null;
	}

	/**
	 * Get the message to include in the reflog.
	 *
	 * @return message the caller wants to include in the reflog; null if the
	 *         update should not be logged.
	 * @since 4.9
	 */
	@Nullable
	public String getRefLogMessage() {
		return refLogMessage;
	}

	/**
	 * Check whether the reflog message should include the result of the update,
	 * such as fast-forward or force-update.
	 *
	 * @return true if the message should include the result.
	 * @since 4.9
	 */
	public boolean isRefLogIncludingResult() {
		return refLogIncludeResult;
	}

	/**
	 * Check whether the reflog should be written regardless of repo defaults.
	 *
	 * @return whether force writing is enabled; {@code null} if
	 *         {@code #setForceRefLog(boolean)} was never called.
	 * @since 4.9
	 */
	@Nullable
	public Boolean isForceRefLog() {
		return forceRefLog;
	}

	/**
	 * Set the status of this command.
	 *
	 * @param s
	 *            the new status code for this command.
	 */
	public void setResult(final Result s) {
		setResult(s, null);
	}

	/**
	 * Set the status of this command.
	 *
	 * @param s
	 *            new status code for this command.
	 * @param m
	 *            optional message explaining the new status.
	 */
	public void setResult(final Result s, final String m) {
		status = s;
		message = m;
	}

	/**
	 * Update the type of this command by checking for fast-forward.
	 * <p>
	 * If the command's current type is UPDATE, a merge test will be performed
	 * using the supplied RevWalk to determine if {@link #getOldId()} is fully
	 * merged into {@link #getNewId()}. If some commits are not merged the
	 * update type is changed to
	 * {@link org.eclipse.jgit.transport.ReceiveCommand.Type#UPDATE_NONFASTFORWARD}.
	 *
	 * @param walk
	 *            an instance to perform the merge test with. The caller must
	 *            allocate and release this object.
	 * @throws java.io.IOException
	 *             either oldId or newId is not accessible in the repository
	 *             used by the RevWalk. This usually indicates data corruption,
	 *             and the command cannot be processed.
	 */
	public void updateType(RevWalk walk) throws IOException {
		if (typeIsCorrect)
			return;
		if (type == Type.UPDATE && !AnyObjectId.equals(oldId, newId)) {
			RevObject o = walk.parseAny(oldId);
			RevObject n = walk.parseAny(newId);
			if (!(o instanceof RevCommit)
					|| !(n instanceof RevCommit)
					|| !walk.isMergedInto((RevCommit) o, (RevCommit) n))
				setType(Type.UPDATE_NONFASTFORWARD);
		}
		typeIsCorrect = true;
	}

	/**
	 * Execute this command during a receive-pack session.
	 * <p>
	 * Sets the status of the command as a side effect.
	 *
	 * @param rp
	 *            receive-pack session.
	 * @since 2.0
	 */
	public void execute(final BaseReceivePack rp) {
		try {
			String expTarget = getOldSymref();
			boolean detach = getNewSymref() != null
					|| (type == Type.DELETE && expTarget != null);
			RefUpdate ru = rp.getRepository().updateRef(getRefName(), detach);
			if (expTarget != null) {
				if (!ru.getRef().isSymbolic() || !ru.getRef().getTarget()
						.getName().equals(expTarget)) {
					setResult(Result.LOCK_FAILURE);
					return;
				}
			}

			ru.setRefLogIdent(rp.getRefLogIdent());
			ru.setRefLogMessage(refLogMessage, refLogIncludeResult);
			switch (getType()) {
			case DELETE:
				if (!ObjectId.zeroId().equals(getOldId())) {
					// We can only do a CAS style delete if the client
					// didn't bork its delete request by sending the
					// wrong zero id rather than the advertised one.
					//
					ru.setExpectedOldObjectId(getOldId());
				}
				ru.setForceUpdate(true);
				setResult(ru.delete(rp.getRevWalk()));
				break;

			case CREATE:
			case UPDATE:
			case UPDATE_NONFASTFORWARD:
				ru.setForceUpdate(rp.isAllowNonFastForwards());
				ru.setExpectedOldObjectId(getOldId());
				ru.setRefLogMessage("push", true); //$NON-NLS-1$
				if (getNewSymref() != null) {
					setResult(ru.link(getNewSymref()));
				} else {
					ru.setNewObjectId(getNewId());
					setResult(ru.update(rp.getRevWalk()));
				}
				break;
			}
		} catch (IOException err) {
			reject(err);
		}
	}

	void setRef(final Ref r) {
		ref = r;
	}

	void setType(final Type t) {
		type = t;
	}

	void setTypeFastForwardUpdate() {
		type = Type.UPDATE;
		typeIsCorrect = true;
	}

	/**
	 * Set the result of this command.
	 *
	 * @param r
	 *            the new result code for this command.
	 */
	public void setResult(RefUpdate.Result r) {
		switch (r) {
		case NOT_ATTEMPTED:
			setResult(Result.NOT_ATTEMPTED);
			break;

		case LOCK_FAILURE:
		case IO_FAILURE:
			setResult(Result.LOCK_FAILURE);
			break;

		case NO_CHANGE:
		case NEW:
		case FORCED:
		case FAST_FORWARD:
			setResult(Result.OK);
			break;

		case REJECTED:
			setResult(Result.REJECTED_NONFASTFORWARD);
			break;

		case REJECTED_CURRENT_BRANCH:
			setResult(Result.REJECTED_CURRENT_BRANCH);
			break;

		case REJECTED_MISSING_OBJECT:
			setResult(Result.REJECTED_MISSING_OBJECT);
			break;

		case REJECTED_OTHER_REASON:
			setResult(Result.REJECTED_OTHER_REASON);
			break;

		default:
			setResult(Result.REJECTED_OTHER_REASON, r.name());
			break;
		}
	}

	void reject(IOException err) {
		setResult(Result.REJECTED_OTHER_REASON, MessageFormat.format(
				JGitText.get().lockError, err.getMessage()));
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		return getType().name() + ": " + getOldId().name() + " "
				+ getNewId().name() + " " + getRefName();
	}
}
