/*
 * 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.ReceivePack}.
 * <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.ReceivePack}.
	 *
	 * @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.ReceivePack}.
	 *
	 * @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.isEqual(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.isEqual(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(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(Result s, 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.isEqual(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(ReceivePack 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(Ref r) {
		ref = r;
	}

	void setType(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();
	}
}
