/*
 * Copyright (C) 2008-2010, Google Inc.
 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
 * 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.pack;

import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.transport.PackedObjectInfo;

/**
 * Per-object state used by
 * {@link org.eclipse.jgit.internal.storage.pack.PackWriter}.
 * <p>
 * {@code PackWriter} uses this class to track the things it needs to include in
 * the newly generated pack file, and how to efficiently obtain the raw data for
 * each object as they are written to the output stream.
 */
public class ObjectToPack extends PackedObjectInfo {
	private static final int REUSE_AS_IS = 1 << 0;
	private static final int DELTA_ATTEMPTED = 1 << 1;
	private static final int DO_NOT_DELTA = 1 << 2;
	private static final int EDGE = 1 << 3;
	private static final int ATTEMPT_DELTA_MASK = REUSE_AS_IS | DELTA_ATTEMPTED;
	private static final int TYPE_SHIFT = 5;
	private static final int EXT_SHIFT = 8;
	private static final int EXT_MASK = 0xf;
	private static final int DELTA_SHIFT = 12;
	private static final int NON_EXT_MASK = ~(EXT_MASK << EXT_SHIFT);
	private static final int NON_DELTA_MASK = 0xfff;

	/** Other object being packed that this will delta against. */
	private ObjectId deltaBase;

	/**
	 * Bit field, from bit 0 to bit 31:
	 * <ul>
	 * <li>1 bit: canReuseAsIs</li>
	 * <li>1 bit: deltaAttempted</li>
	 * <li>1 bit: doNotDelta</li>
	 * <li>1 bit: edgeObject</li>
	 * <li>1 bit: unused</li>
	 * <li>3 bits: type</li>
	 * <li>4 bits: subclass flags (if any)</li>
	 * <li>--</li>
	 * <li>20 bits: deltaDepth</li>
	 * </ul>
	 */
	private int flags;

	/** Hash of the object's tree path. */
	private int pathHash;

	/** If present, deflated delta instruction stream for this object. */
	private DeltaCache.Ref cachedDelta;

	/**
	 * Construct for the specified object id.
	 *
	 * @param src
	 *            object id of object for packing
	 * @param type
	 *            real type code of the object, not its in-pack type.
	 */
	public ObjectToPack(AnyObjectId src, int type) {
		super(src);
		flags = type << TYPE_SHIFT;
	}

	/**
	 * Get delta base object id if object is going to be packed in delta
	 * representation
	 *
	 * @return delta base object id if object is going to be packed in delta
	 *         representation; null otherwise - if going to be packed as a whole
	 *         object.
	 */
	public final ObjectId getDeltaBaseId() {
		return deltaBase;
	}

	/**
	 * Get delta base object to pack if object is going to be packed in delta
	 * representation and delta is specified as object to pack
	 *
	 * @return delta base object to pack if object is going to be packed in
	 *         delta representation and delta is specified as object to pack;
	 *         null otherwise - if going to be packed as a whole object or delta
	 *         base is specified only as id.
	 */
	public final ObjectToPack getDeltaBase() {
		if (deltaBase instanceof ObjectToPack)
			return (ObjectToPack) deltaBase;
		return null;
	}

	/**
	 * Set delta base for the object. Delta base set by this method is used
	 * by {@link PackWriter} to write object - determines its representation
	 * in a created pack.
	 *
	 * @param deltaBase
	 *            delta base object or null if object should be packed as a
	 *            whole object.
	 *
	 */
	final void setDeltaBase(ObjectId deltaBase) {
		this.deltaBase = deltaBase;
	}

	final void setCachedDelta(DeltaCache.Ref data) {
		cachedDelta = data;
	}

	final DeltaCache.Ref popCachedDelta() {
		DeltaCache.Ref r = cachedDelta;
		if (r != null)
			cachedDelta = null;
		return r;
	}

	final void clearDeltaBase() {
		this.deltaBase = null;

		if (cachedDelta != null) {
			cachedDelta.clear();
			cachedDelta.enqueue();
			cachedDelta = null;
		}
	}

	/**
	 * Whether object is going to be written as delta
	 *
	 * @return true if object is going to be written as delta; false otherwise.
	 */
	public final boolean isDeltaRepresentation() {
		return deltaBase != null;
	}

	/**
	 * Check if object is already written in a pack. This information is
	 * used to achieve delta-base precedence in a pack file.
	 *
	 * @return true if object is already written; false otherwise.
	 */
	public final boolean isWritten() {
		return 1 < getOffset(); // markWantWrite sets 1.
	}

	/** {@inheritDoc} */
	@Override
	public final int getType() {
		return (flags >> TYPE_SHIFT) & 0x7;
	}

	final int getDeltaDepth() {
		return flags >>> DELTA_SHIFT;
	}

	final void setDeltaDepth(int d) {
		flags = (d << DELTA_SHIFT) | (flags & NON_DELTA_MASK);
	}

	final int getChainLength() {
		return getDeltaDepth();
	}

	final void setChainLength(int len) {
		setDeltaDepth(len);
	}

	final void clearChainLength() {
		flags &= NON_DELTA_MASK;
	}

	final boolean wantWrite() {
		return getOffset() == 1;
	}

	final void markWantWrite() {
		setOffset(1);
	}

	/**
	 * Whether an existing representation was selected to be reused as-is into
	 * the pack stream.
	 *
	 * @return true if an existing representation was selected to be reused
	 *         as-is into the pack stream.
	 */
	public final boolean isReuseAsIs() {
		return (flags & REUSE_AS_IS) != 0;
	}

	final void setReuseAsIs() {
		flags |= REUSE_AS_IS;
	}

	/**
	 * Forget the reuse information previously stored.
	 * <p>
	 * Implementations may subclass this method, but they must also invoke the
	 * super version with {@code super.clearReuseAsIs()} to ensure the flag is
	 * properly cleared for the writer.
	 */
	protected void clearReuseAsIs() {
		flags &= ~REUSE_AS_IS;
	}

	final boolean isDoNotDelta() {
		return (flags & DO_NOT_DELTA) != 0;
	}

	final void setDoNotDelta() {
		flags |= DO_NOT_DELTA;
	}

	final boolean isEdge() {
		return (flags & EDGE) != 0;
	}

	final void setEdge() {
		flags |= EDGE;
	}

	final boolean doNotAttemptDelta() {
		// Do not attempt if delta attempted and object reuse.
		return (flags & ATTEMPT_DELTA_MASK) == ATTEMPT_DELTA_MASK;
	}

	final void setDeltaAttempted(boolean deltaAttempted) {
		if (deltaAttempted)
			flags |= DELTA_ATTEMPTED;
		else
			flags &= ~DELTA_ATTEMPTED;
	}

	/**
	 * Get the extended flags on this object, in the range [0x0, 0xf].
	 *
	 * @return the extended flags on this object, in the range [0x0, 0xf].
	 */
	protected final int getExtendedFlags() {
		return (flags >>> EXT_SHIFT) & EXT_MASK;
	}

	/**
	 * Determine if a particular extended flag bit has been set.
	 *
	 * This implementation may be faster than calling
	 * {@link #getExtendedFlags()} and testing the result.
	 *
	 * @param flag
	 *            the flag mask to test, must be between 0x0 and 0xf.
	 * @return true if any of the bits matching the mask are non-zero.
	 */
	protected final boolean isExtendedFlag(int flag) {
		return (flags & (flag << EXT_SHIFT)) != 0;
	}

	/**
	 * Set an extended flag bit.
	 *
	 * This implementation is more efficient than getting the extended flags,
	 * adding the bit, and setting them all back.
	 *
	 * @param flag
	 *            the bits to set, must be between 0x0 and 0xf.
	 */
	protected final void setExtendedFlag(int flag) {
		flags |= (flag & EXT_MASK) << EXT_SHIFT;
	}

	/**
	 * Clear an extended flag bit.
	 *
	 * This implementation is more efficient than getting the extended flags,
	 * removing the bit, and setting them all back.
	 *
	 * @param flag
	 *            the bits to clear, must be between 0x0 and 0xf.
	 */
	protected final void clearExtendedFlag(int flag) {
		flags &= ~((flag & EXT_MASK) << EXT_SHIFT);
	}

	/**
	 * Set the extended flags used by the subclass.
	 *
	 * Subclass implementations may store up to 4 bits of information inside of
	 * the internal flags field already used by the base ObjectToPack instance.
	 *
	 * @param extFlags
	 *            additional flag bits to store in the flags field. Due to space
	 *            constraints only values [0x0, 0xf] are permitted.
	 */
	protected final void setExtendedFlags(int extFlags) {
		flags = ((extFlags & EXT_MASK) << EXT_SHIFT) | (flags & NON_EXT_MASK);
	}

	final int getFormat() {
		if (isReuseAsIs()) {
			if (isDeltaRepresentation())
				return StoredObjectRepresentation.PACK_DELTA;
			return StoredObjectRepresentation.PACK_WHOLE;
		}
		return StoredObjectRepresentation.FORMAT_OTHER;
	}

	// Overload weight into CRC since we don't need them at the same time.
	final int getWeight() {
		return getCRC();
	}

	final void setWeight(int weight) {
		setCRC(weight);
	}

	final int getPathHash() {
		return pathHash;
	}

	final void setPathHash(int hc) {
		pathHash = hc;
	}

	final int getCachedSize() {
		return pathHash;
	}

	final void setCachedSize(int sz) {
		pathHash = sz;
	}

	/**
	 * Remember a specific representation for reuse at a later time.
	 * <p>
	 * Implementers should remember the representation chosen, so it can be
	 * reused at a later time.
	 * {@link org.eclipse.jgit.internal.storage.pack.PackWriter} may invoke this
	 * method multiple times for the same object, each time saving the current
	 * best representation found.
	 *
	 * @param ref
	 *            the object representation.
	 */
	public void select(StoredObjectRepresentation ref) {
		// Empty by default.
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		StringBuilder buf = new StringBuilder();
		buf.append("ObjectToPack[");
		buf.append(Constants.typeString(getType()));
		buf.append(" ");
		buf.append(name());
		if (wantWrite())
			buf.append(" wantWrite");
		if (isReuseAsIs())
			buf.append(" reuseAsIs");
		if (isDoNotDelta())
			buf.append(" doNotDelta");
		if (isEdge())
			buf.append(" edge");
		if (getDeltaDepth() > 0)
			buf.append(" depth=").append(getDeltaDepth());
		if (isDeltaRepresentation()) {
			if (getDeltaBase() != null)
				buf.append(" base=inpack:").append(getDeltaBase().name());
			else
				buf.append(" base=edge:").append(getDeltaBaseId().name());
		}
		if (isWritten())
			buf.append(" offset=").append(getOffset());
		buf.append("]");
		return buf.toString();
	}
}
