/*
 * Copyright (C) 2016, 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.internal.storage.reftree;

import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.Constants.encode;
import static org.eclipse.jgit.lib.FileMode.TYPE_GITLINK;
import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK;
import static org.eclipse.jgit.lib.Ref.Storage.NETWORK;
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 org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceiveCommand.Result;

/**
 * Command to create, update or delete an entry inside a
 * {@link org.eclipse.jgit.internal.storage.reftree.RefTree}.
 * <p>
 * Unlike {@link org.eclipse.jgit.transport.ReceiveCommand} (which can only
 * update a reference to an {@link org.eclipse.jgit.lib.ObjectId}), a RefTree
 * Command can also create, modify or delete symbolic references to a target
 * reference.
 * <p>
 * RefTree Commands may wrap a {@code ReceiveCommand} to allow callers to
 * process an existing ReceiveCommand against a RefTree.
 * <p>
 * Commands should be passed into
 * {@link org.eclipse.jgit.internal.storage.reftree.RefTree#apply(java.util.Collection)}
 * for processing.
 */
public class Command {
	/**
	 * 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}.
	 * If {@code why} is non-null its contents will be used as the message for
	 * the first command status.
	 *
	 * @param commands
	 *            commands to mark as failed.
	 * @param why
	 *            optional message to set on the first aborted command.
	 */
	public static void abort(Iterable<Command> commands, @Nullable String why) {
		if (why == null || why.isEmpty()) {
			why = JGitText.get().transactionAborted;
		}
		for (Command c : commands) {
			if (c.getResult() == NOT_ATTEMPTED) {
				c.setResult(REJECTED_OTHER_REASON, why);
				why = JGitText.get().transactionAborted;
			}
		}
	}

	private final Ref oldRef;
	private final Ref newRef;
	private final ReceiveCommand cmd;
	private Result result;

	/**
	 * Create a command to create, update or delete a reference.
	 * <p>
	 * At least one of {@code oldRef} or {@code newRef} must be supplied.
	 *
	 * @param oldRef
	 *            expected value. Null if the ref should not exist.
	 * @param newRef
	 *            desired value, must be peeled if not null and not symbolic.
	 *            Null to delete the ref.
	 */
	public Command(@Nullable Ref oldRef, @Nullable Ref newRef) {
		this.oldRef = oldRef;
		this.newRef = newRef;
		this.cmd = null;
		this.result = NOT_ATTEMPTED;

		if (oldRef == null && newRef == null) {
			throw new IllegalArgumentException();
		}
		if (newRef != null && !newRef.isPeeled() && !newRef.isSymbolic()) {
			throw new IllegalArgumentException();
		}
		if (oldRef != null && newRef != null
				&& !oldRef.getName().equals(newRef.getName())) {
			throw new IllegalArgumentException();
		}
	}

	/**
	 * Construct a RefTree command wrapped around a ReceiveCommand.
	 *
	 * @param rw
	 *            walk instance to peel the {@code newId}.
	 * @param cmd
	 *            command received from a push client.
	 * @throws org.eclipse.jgit.errors.MissingObjectException
	 *             {@code oldId} or {@code newId} is missing.
	 * @throws java.io.IOException
	 *             {@code oldId} or {@code newId} cannot be peeled.
	 */
	public Command(RevWalk rw, ReceiveCommand cmd)
			throws MissingObjectException, IOException {
		this.oldRef = toRef(rw, cmd.getOldId(), cmd.getOldSymref(),
				cmd.getRefName(), false);
		this.newRef = toRef(rw, cmd.getNewId(), cmd.getNewSymref(),
				cmd.getRefName(), true);
		this.cmd = cmd;
	}

	static Ref toRef(RevWalk rw, ObjectId id, @Nullable String target,
			String name, boolean mustExist)
			throws MissingObjectException, IOException {
		if (target != null) {
			return new SymbolicRef(name,
					new ObjectIdRef.Unpeeled(NETWORK, target, id));
		} else if (ObjectId.zeroId().equals(id)) {
			return null;
		}

		try {
			RevObject o = rw.parseAny(id);
			if (o instanceof RevTag) {
				RevObject p = rw.peel(o);
				return new ObjectIdRef.PeeledTag(NETWORK, name, id, p.copy());
			}
			return new ObjectIdRef.PeeledNonTag(NETWORK, name, id);
		} catch (MissingObjectException e) {
			if (mustExist) {
				throw e;
			}
			return new ObjectIdRef.Unpeeled(NETWORK, name, id);
		}
	}

	/**
	 * Get name of the reference affected by this command.
	 *
	 * @return name of the reference affected by this command.
	 */
	public String getRefName() {
		if (cmd != null) {
			return cmd.getRefName();
		} else if (newRef != null) {
			return newRef.getName();
		}
		return oldRef.getName();
	}

	/**
	 * Set the result of this command.
	 *
	 * @param result
	 *            the command result.
	 */
	public void setResult(Result result) {
		setResult(result, null);
	}

	/**
	 * Set the result of this command.
	 *
	 * @param result
	 *            the command result.
	 * @param why
	 *            optional message explaining the result status.
	 */
	public void setResult(Result result, @Nullable String why) {
		if (cmd != null) {
			cmd.setResult(result, why);
		} else {
			this.result = result;
		}
	}

	/**
	 * Get result of executing this command.
	 *
	 * @return result of executing this command.
	 */
	public Result getResult() {
		return cmd != null ? cmd.getResult() : result;
	}

	/**
	 * Get optional message explaining command failure.
	 *
	 * @return optional message explaining command failure.
	 */
	@Nullable
	public String getMessage() {
		return cmd != null ? cmd.getMessage() : null;
	}

	/**
	 * Old peeled reference.
	 *
	 * @return the old reference; null if the command is creating the reference.
	 */
	@Nullable
	public Ref getOldRef() {
		return oldRef;
	}

	/**
	 * New peeled reference.
	 *
	 * @return the new reference; null if the command is deleting the reference.
	 */
	@Nullable
	public Ref getNewRef() {
		return newRef;
	}

	/** {@inheritDoc} */
	@Override
	public String toString() {
		StringBuilder s = new StringBuilder();
		append(s, oldRef, "CREATE"); //$NON-NLS-1$
		s.append(' ');
		append(s, newRef, "DELETE"); //$NON-NLS-1$
		s.append(' ').append(getRefName());
		s.append(' ').append(getResult());
		if (getMessage() != null) {
			s.append(' ').append(getMessage());
		}
		return s.toString();
	}

	private static void append(StringBuilder s, Ref r, String nullName) {
		if (r == null) {
			s.append(nullName);
		} else if (r.isSymbolic()) {
			s.append(r.getTarget().getName());
		} else {
			ObjectId id = r.getObjectId();
			if (id != null) {
				s.append(id.name());
			}
		}
	}

	/**
	 * Check the entry is consistent with either the old or the new ref.
	 *
	 * @param entry
	 *            current entry; null if the entry does not exist.
	 * @return true if entry matches {@link #getOldRef()} or
	 *         {@link #getNewRef()}; otherwise false.
	 */
	boolean checkRef(@Nullable DirCacheEntry entry) {
		if (entry != null && entry.getRawMode() == 0) {
			entry = null;
		}
		return check(entry, oldRef) || check(entry, newRef);
	}

	private static boolean check(@Nullable DirCacheEntry cur,
			@Nullable Ref exp) {
		if (cur == null) {
			// Does not exist, ok if oldRef does not exist.
			return exp == null;
		} else if (exp == null) {
			// Expected to not exist, but currently exists, fail.
			return false;
		}

		if (exp.isSymbolic()) {
			String dst = exp.getTarget().getName();
			return cur.getRawMode() == TYPE_SYMLINK
					&& cur.getObjectId().equals(symref(dst));
		}

		return cur.getRawMode() == TYPE_GITLINK
				&& cur.getObjectId().equals(exp.getObjectId());
	}

	static ObjectId symref(String s) {
		@SuppressWarnings("resource")
		ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
		return fmt.idFor(OBJ_BLOB, encode(s));
	}
}
