/*
 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * 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 org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;

/**
 * Update of a locally stored tracking branch.
 */
public class TrackingRefUpdate {
	private final String remoteName;
	final String localName;
	boolean forceUpdate;
	ObjectId oldObjectId;
	ObjectId newObjectId;

	private RefUpdate.Result result;
	private ReceiveCommand cmd;

	TrackingRefUpdate(
			boolean canForceUpdate,
			String remoteName,
			String localName,
			AnyObjectId oldValue,
			AnyObjectId newValue) {
		this.remoteName = remoteName;
		this.localName = localName;
		this.forceUpdate = canForceUpdate;
		this.oldObjectId = oldValue.copy();
		this.newObjectId = newValue.copy();
	}

	/**
	 * Get the name of the remote ref.
	 * <p>
	 * Usually this is of the form "refs/heads/master".
	 *
	 * @return the name used within the remote repository.
	 */
	public String getRemoteName() {
		return remoteName;
	}

	/**
	 * Get the name of the local tracking ref.
	 * <p>
	 * Usually this is of the form "refs/remotes/origin/master".
	 *
	 * @return the name used within this local repository.
	 */
	public String getLocalName() {
		return localName;
	}

	/**
	 * Get the new value the ref will be (or was) updated to.
	 *
	 * @return new value. Null if the caller has not configured it.
	 */
	public ObjectId getNewObjectId() {
		return newObjectId;
	}

	/**
	 * The old value of the ref, prior to the update being attempted.
	 * <p>
	 * This value may differ before and after the update method. Initially it is
	 * populated with the value of the ref before the lock is taken, but the old
	 * value may change if someone else modified the ref between the time we
	 * last read it and when the ref was locked for update.
	 *
	 * @return the value of the ref prior to the update being attempted.
	 */
	public ObjectId getOldObjectId() {
		return oldObjectId;
	}

	/**
	 * Get the status of this update.
	 *
	 * @return the status of the update.
	 */
	public RefUpdate.Result getResult() {
		return result;
	}

	void setResult(RefUpdate.Result result) {
		this.result = result;
	}

	/**
	 * Get this update wrapped by a ReceiveCommand.
	 *
	 * @return this update wrapped by a ReceiveCommand.
	 * @since 3.4
	 */
	public ReceiveCommand asReceiveCommand() {
		if (cmd == null)
			cmd = new Command();
		return cmd;
	}

	final class Command extends ReceiveCommand {
		Command() {
			super(oldObjectId, newObjectId, localName);
		}

		boolean canForceUpdate() {
			return forceUpdate;
		}

		@Override
		public void setResult(RefUpdate.Result status) {
			result = status;
			super.setResult(status);
		}

		@Override
		public void setResult(ReceiveCommand.Result status) {
			result = decode(status);
			super.setResult(status);
		}

		@Override
		public void setResult(ReceiveCommand.Result status, String msg) {
			result = decode(status);
			super.setResult(status, msg);
		}

		private RefUpdate.Result decode(ReceiveCommand.Result status) {
			switch (status) {
			case OK:
				if (AnyObjectId.isEqual(oldObjectId, newObjectId))
					return RefUpdate.Result.NO_CHANGE;
				switch (getType()) {
				case CREATE:
					return RefUpdate.Result.NEW;
				case UPDATE:
					return RefUpdate.Result.FAST_FORWARD;
				case DELETE:
				case UPDATE_NONFASTFORWARD:
				default:
					return RefUpdate.Result.FORCED;
				}

			case REJECTED_NOCREATE:
			case REJECTED_NODELETE:
			case REJECTED_NONFASTFORWARD:
				return RefUpdate.Result.REJECTED;
			case REJECTED_CURRENT_BRANCH:
				return RefUpdate.Result.REJECTED_CURRENT_BRANCH;
			case REJECTED_MISSING_OBJECT:
				return RefUpdate.Result.IO_FAILURE;
			case LOCK_FAILURE:
			case NOT_ATTEMPTED:
			case REJECTED_OTHER_REASON:
			default:
				return RefUpdate.Result.LOCK_FAILURE;
			}
		}
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("TrackingRefUpdate[");
		sb.append(remoteName);
		sb.append(" -> ");
		sb.append(localName);
		if (forceUpdate)
			sb.append(" (forced)");
		sb.append(" ");
		sb.append(oldObjectId == null ? "" : oldObjectId.abbreviate(7).name());
		sb.append("..");
		sb.append(newObjectId == null ? "" : newObjectId.abbreviate(7).name());
		sb.append("]");
		return sb.toString();
	}
}
