/*
 * Copyright (C) 2015, Matthias Sohn <matthias.sohn@sap.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.lfs.lib;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.ByteBuffer;

import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.References;

/**
 * A (possibly mutable) SHA-256 abstraction.
 * <p>
 * If this is an instance of
 * {@link org.eclipse.jgit.lfs.lib.MutableLongObjectId} the concept of equality
 * with this instance can alter at any time, if this instance is modified to
 * represent a different object name.
 *
 * Ported to SHA-256 from {@link org.eclipse.jgit.lib.AnyObjectId}
 *
 * @since 4.3
 */
public abstract class AnyLongObjectId implements Comparable<AnyLongObjectId> {

	/**
	 * Compare two object identifier byte sequences for equality.
	 *
	 * @param firstObjectId
	 *            the first identifier to compare. Must not be null.
	 * @param secondObjectId
	 *            the second identifier to compare. Must not be null.
	 * @return true if the two identifiers are the same.
	 * @deprecated use {@link #isEqual(AnyLongObjectId, AnyLongObjectId)}
	 *             instead.
	 */
	@Deprecated
	@SuppressWarnings("AmbiguousMethodReference")
	public static boolean equals(final AnyLongObjectId firstObjectId,
			final AnyLongObjectId secondObjectId) {
		return isEqual(firstObjectId, secondObjectId);
	}

	/**
	 * Compare two object identifier byte sequences for equality.
	 *
	 * @param firstObjectId
	 *            the first identifier to compare. Must not be null.
	 * @param secondObjectId
	 *            the second identifier to compare. Must not be null.
	 * @return true if the two identifiers are the same.
	 * @since 5.4
	 */
	public static boolean isEqual(final AnyLongObjectId firstObjectId,
			final AnyLongObjectId secondObjectId) {
		if (References.isSameObject(firstObjectId, secondObjectId)) {
			return true;
		}

		// We test word 2 first as odds are someone already used our
		// word 1 as a hash code, and applying that came up with these
		// two instances we are comparing for equality. Therefore the
		// first two words are very likely to be identical. We want to
		// break away from collisions as quickly as possible.
		//
		return firstObjectId.w2 == secondObjectId.w2
				&& firstObjectId.w3 == secondObjectId.w3
				&& firstObjectId.w4 == secondObjectId.w4
				&& firstObjectId.w1 == secondObjectId.w1;
	}

	long w1;

	long w2;

	long w3;

	long w4;

	/**
	 * Get the first 8 bits of the LongObjectId.
	 *
	 * This is a faster version of {@code getByte(0)}.
	 *
	 * @return a discriminator usable for a fan-out style map. Returned values
	 *         are unsigned and thus are in the range [0,255] rather than the
	 *         signed byte range of [-128, 127].
	 */
	public final int getFirstByte() {
		return (int) (w1 >>> 56);
	}

	/**
	 * Get the second 8 bits of the LongObjectId.
	 *
	 * @return a discriminator usable for a fan-out style map. Returned values
	 *         are unsigned and thus are in the range [0,255] rather than the
	 *         signed byte range of [-128, 127].
	 */
	public final int getSecondByte() {
		return (int) ((w1 >>> 48) & 0xff);
	}

	/**
	 * Get any byte from the LongObjectId.
	 *
	 * Callers hard-coding {@code getByte(0)} should instead use the much faster
	 * special case variant {@link #getFirstByte()}.
	 *
	 * @param index
	 *            index of the byte to obtain from the raw form of the
	 *            LongObjectId. Must be in range [0,
	 *            {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}).
	 * @return the value of the requested byte at {@code index}. Returned values
	 *         are unsigned and thus are in the range [0,255] rather than the
	 *         signed byte range of [-128, 127].
	 * @throws java.lang.ArrayIndexOutOfBoundsException
	 *             {@code index} is less than 0, equal to
	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH},
	 *             or greater than
	 *             {@link org.eclipse.jgit.lfs.lib.Constants#LONG_OBJECT_ID_LENGTH}.
	 */
	public final int getByte(int index) {
		long w;
		switch (index >> 3) {
		case 0:
			w = w1;
			break;
		case 1:
			w = w2;
			break;
		case 2:
			w = w3;
			break;
		case 3:
			w = w4;
			break;
		default:
			throw new ArrayIndexOutOfBoundsException(index);
		}

		return (int) ((w >>> (8 * (15 - (index & 15)))) & 0xff);
	}

	/**
	 * {@inheritDoc}
	 *
	 * Compare this LongObjectId to another and obtain a sort ordering.
	 */
	@Override
	public final int compareTo(AnyLongObjectId other) {
		if (this == other)
			return 0;

		int cmp;

		cmp = NB.compareUInt64(w1, other.w1);
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w2, other.w2);
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w3, other.w3);
		if (cmp != 0)
			return cmp;

		return NB.compareUInt64(w4, other.w4);
	}

	/**
	 * Compare this LongObjectId to a network-byte-order LongObjectId.
	 *
	 * @param bs
	 *            array containing the other LongObjectId in network byte order.
	 * @param p
	 *            position within {@code bs} to start the compare at. At least
	 *            32 bytes, starting at this position are required.
	 * @return a negative integer, zero, or a positive integer as this object is
	 *         less than, equal to, or greater than the specified object.
	 */
	public final int compareTo(byte[] bs, int p) {
		int cmp;

		cmp = NB.compareUInt64(w1, NB.decodeInt64(bs, p));
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w2, NB.decodeInt64(bs, p + 8));
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w3, NB.decodeInt64(bs, p + 16));
		if (cmp != 0)
			return cmp;

		return NB.compareUInt64(w4, NB.decodeInt64(bs, p + 24));
	}

	/**
	 * Compare this LongObjectId to a network-byte-order LongObjectId.
	 *
	 * @param bs
	 *            array containing the other LongObjectId in network byte order.
	 * @param p
	 *            position within {@code bs} to start the compare at. At least 4
	 *            longs, starting at this position are required.
	 * @return a negative integer, zero, or a positive integer as this object is
	 *         less than, equal to, or greater than the specified object.
	 */
	public final int compareTo(long[] bs, int p) {
		int cmp;

		cmp = NB.compareUInt64(w1, bs[p]);
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w2, bs[p + 1]);
		if (cmp != 0)
			return cmp;

		cmp = NB.compareUInt64(w3, bs[p + 2]);
		if (cmp != 0)
			return cmp;

		return NB.compareUInt64(w4, bs[p + 3]);
	}

	/**
	 * Tests if this LongObjectId starts with the given abbreviation.
	 *
	 * @param abbr
	 *            the abbreviation.
	 * @return true if this LongObjectId begins with the abbreviation; else
	 *         false.
	 */
	public boolean startsWith(AbbreviatedLongObjectId abbr) {
		return abbr.prefixCompare(this) == 0;
	}

	/** {@inheritDoc} */
	@Override
	public final int hashCode() {
		return (int) (w1 >> 32);
	}

	/**
	 * Determine if this LongObjectId has exactly the same value as another.
	 *
	 * @param other
	 *            the other id to compare to. May be null.
	 * @return true only if both LongObjectIds have identical bits.
	 */
	@SuppressWarnings({ "NonOverridingEquals", "AmbiguousMethodReference" })
	public final boolean equals(AnyLongObjectId other) {
		return other != null ? equals(this, other) : false;
	}

	/** {@inheritDoc} */
	@Override
	public final boolean equals(Object o) {
		if (o instanceof AnyLongObjectId) {
			return equals((AnyLongObjectId) o);
		}
		return false;
	}

	/**
	 * Copy this LongObjectId to an output writer in raw binary.
	 *
	 * @param w
	 *            the buffer to copy to. Must be in big endian order.
	 */
	public void copyRawTo(ByteBuffer w) {
		w.putLong(w1);
		w.putLong(w2);
		w.putLong(w3);
		w.putLong(w4);
	}

	/**
	 * Copy this LongObjectId to a byte array.
	 *
	 * @param b
	 *            the buffer to copy to.
	 * @param o
	 *            the offset within b to write at.
	 */
	public void copyRawTo(byte[] b, int o) {
		NB.encodeInt64(b, o, w1);
		NB.encodeInt64(b, o + 8, w2);
		NB.encodeInt64(b, o + 16, w3);
		NB.encodeInt64(b, o + 24, w4);
	}

	/**
	 * Copy this LongObjectId to an long array.
	 *
	 * @param b
	 *            the buffer to copy to.
	 * @param o
	 *            the offset within b to write at.
	 */
	public void copyRawTo(long[] b, int o) {
		b[o] = w1;
		b[o + 1] = w2;
		b[o + 2] = w3;
		b[o + 3] = w4;
	}

	/**
	 * Copy this LongObjectId to an output writer in raw binary.
	 *
	 * @param w
	 *            the stream to write to.
	 * @throws java.io.IOException
	 *             the stream writing failed.
	 */
	public void copyRawTo(OutputStream w) throws IOException {
		writeRawLong(w, w1);
		writeRawLong(w, w2);
		writeRawLong(w, w3);
		writeRawLong(w, w4);
	}

	private static void writeRawLong(OutputStream w, long v)
			throws IOException {
		w.write((int) (v >>> 56));
		w.write((int) (v >>> 48));
		w.write((int) (v >>> 40));
		w.write((int) (v >>> 32));
		w.write((int) (v >>> 24));
		w.write((int) (v >>> 16));
		w.write((int) (v >>> 8));
		w.write((int) v);
	}

	/**
	 * Copy this LongObjectId to an output writer in hex format.
	 *
	 * @param w
	 *            the stream to copy to.
	 * @throws java.io.IOException
	 *             the stream writing failed.
	 */
	public void copyTo(OutputStream w) throws IOException {
		w.write(toHexByteArray());
	}

	/**
	 * Copy this LongObjectId to a byte array in hex format.
	 *
	 * @param b
	 *            the buffer to copy to.
	 * @param o
	 *            the offset within b to write at.
	 */
	public void copyTo(byte[] b, int o) {
		formatHexByte(b, o + 0, w1);
		formatHexByte(b, o + 16, w2);
		formatHexByte(b, o + 32, w3);
		formatHexByte(b, o + 48, w4);
	}

	/**
	 * Copy this LongObjectId to a ByteBuffer in hex format.
	 *
	 * @param b
	 *            the buffer to copy to.
	 */
	public void copyTo(ByteBuffer b) {
		b.put(toHexByteArray());
	}

	private byte[] toHexByteArray() {
		final byte[] dst = new byte[Constants.LONG_OBJECT_ID_STRING_LENGTH];
		formatHexByte(dst, 0, w1);
		formatHexByte(dst, 16, w2);
		formatHexByte(dst, 32, w3);
		formatHexByte(dst, 48, w4);
		return dst;
	}

	private static final byte[] hexbyte = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	private static void formatHexByte(byte[] dst, int p, long w) {
		int o = p + 15;
		while (o >= p && w != 0) {
			dst[o--] = hexbyte[(int) (w & 0xf)];
			w >>>= 4;
		}
		while (o >= p)
			dst[o--] = '0';
	}

	/**
	 * Copy this LongObjectId to an output writer in hex format.
	 *
	 * @param w
	 *            the stream to copy to.
	 * @throws java.io.IOException
	 *             the stream writing failed.
	 */
	public void copyTo(Writer w) throws IOException {
		w.write(toHexCharArray());
	}

	/**
	 * Copy this LongObjectId to an output writer in hex format.
	 *
	 * @param tmp
	 *            temporary char array to buffer construct into before writing.
	 *            Must be at least large enough to hold 2 digits for each byte
	 *            of object id (64 characters or larger).
	 * @param w
	 *            the stream to copy to.
	 * @throws java.io.IOException
	 *             the stream writing failed.
	 */
	public void copyTo(char[] tmp, Writer w) throws IOException {
		toHexCharArray(tmp);
		w.write(tmp, 0, Constants.LONG_OBJECT_ID_STRING_LENGTH);
	}

	/**
	 * Copy this LongObjectId to a StringBuilder in hex format.
	 *
	 * @param tmp
	 *            temporary char array to buffer construct into before writing.
	 *            Must be at least large enough to hold 2 digits for each byte
	 *            of object id (64 characters or larger).
	 * @param w
	 *            the string to append onto.
	 */
	public void copyTo(char[] tmp, StringBuilder w) {
		toHexCharArray(tmp);
		w.append(tmp, 0, Constants.LONG_OBJECT_ID_STRING_LENGTH);
	}

	char[] toHexCharArray() {
		final char[] dst = new char[Constants.LONG_OBJECT_ID_STRING_LENGTH];
		toHexCharArray(dst);
		return dst;
	}

	private void toHexCharArray(char[] dst) {
		formatHexChar(dst, 0, w1);
		formatHexChar(dst, 16, w2);
		formatHexChar(dst, 32, w3);
		formatHexChar(dst, 48, w4);
	}

	private static final char[] hexchar = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	static void formatHexChar(char[] dst, int p, long w) {
		int o = p + 15;
		while (o >= p && w != 0) {
			dst[o--] = hexchar[(int) (w & 0xf)];
			w >>>= 4;
		}
		while (o >= p)
			dst[o--] = '0';
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		return "AnyLongObjectId[" + name() + "]";
	}

	/**
	 * Get string form of the SHA-256
	 *
	 * @return string form of the SHA-256, in lower case hexadecimal.
	 */
	public final String name() {
		return new String(toHexCharArray());
	}

	/**
	 * Get string form of the SHA-256
	 *
	 * @return string form of the SHA-256, in lower case hexadecimal.
	 */
	public final String getName() {
		return name();
	}

	/**
	 * Return an abbreviation (prefix) of this object SHA-256.
	 * <p>
	 * This implementation does not guarantee uniqueness. Callers should instead
	 * use
	 * {@link org.eclipse.jgit.lib.ObjectReader#abbreviate(AnyObjectId, int)} to
	 * obtain a unique abbreviation within the scope of a particular object
	 * database.
	 *
	 * @param len
	 *            length of the abbreviated string.
	 * @return SHA-256 abbreviation.
	 */
	public AbbreviatedLongObjectId abbreviate(int len) {
		final long a = AbbreviatedLongObjectId.mask(len, 1, w1);
		final long b = AbbreviatedLongObjectId.mask(len, 2, w2);
		final long c = AbbreviatedLongObjectId.mask(len, 3, w3);
		final long d = AbbreviatedLongObjectId.mask(len, 4, w4);
		return new AbbreviatedLongObjectId(len, a, b, c, d);
	}

	/**
	 * Obtain an immutable copy of this current object.
	 * <p>
	 * Only returns <code>this</code> if this instance is an unsubclassed
	 * instance of {@link org.eclipse.jgit.lfs.lib.LongObjectId}; otherwise a
	 * new instance is returned holding the same value.
	 * <p>
	 * This method is useful to shed any additional memory that may be tied to
	 * the subclass, yet retain the unique identity of the object id for future
	 * lookups within maps and repositories.
	 *
	 * @return an immutable copy, using the smallest memory footprint possible.
	 */
	public final LongObjectId copy() {
		if (getClass() == LongObjectId.class)
			return (LongObjectId) this;
		return new LongObjectId(this);
	}

	/**
	 * Obtain an immutable copy of this current object.
	 * <p>
	 * See {@link #copy()} if <code>this</code> is a possibly subclassed (but
	 * immutable) identity and the application needs a lightweight identity
	 * <i>only</i> reference.
	 *
	 * @return an immutable copy. May be <code>this</code> if this is already an
	 *         immutable instance.
	 */
	public abstract LongObjectId toObjectId();
}
