/*
 * Copyright (C) 2008-2010, Google Inc.
 * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

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.
	}

	@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.
	}

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