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

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.RawParseUtils;

/**
 * A SHA-256 abstraction.
 *
 * Ported to SHA-256 from {@link org.eclipse.jgit.lib.ObjectId}
 *
 * @since 4.3
 */
public class LongObjectId extends AnyLongObjectId implements Serializable {
	private static final long serialVersionUID = 1L;

	private static final LongObjectId ZEROID;

	private static final String ZEROID_STR;

	static {
		ZEROID = new LongObjectId(0L, 0L, 0L, 0L);
		ZEROID_STR = ZEROID.name();
	}

	/**
	 * Get the special all-zero LongObjectId.
	 *
	 * @return the all-zero LongObjectId, often used to stand-in for no object.
	 */
	public static final LongObjectId zeroId() {
		return ZEROID;
	}

	/**
	 * Test a string of characters to verify that it can be interpreted as
	 * LongObjectId.
	 * <p>
	 * If true the string can be parsed with {@link #fromString(String)}.
	 *
	 * @param id
	 *            the string to test.
	 * @return true if the string can converted into an LongObjectId.
	 */
	public static final boolean isId(String id) {
		if (id.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
			return false;
		try {
			for (int i = 0; i < Constants.LONG_OBJECT_ID_STRING_LENGTH; i++) {
				RawParseUtils.parseHexInt4((byte) id.charAt(i));
			}
			return true;
		} catch (ArrayIndexOutOfBoundsException e) {
			return false;
		}
	}

	/**
	 * Convert a LongObjectId into a hex string representation.
	 *
	 * @param i
	 *            the id to convert. May be null.
	 * @return the hex string conversion of this id's content.
	 */
	public static final String toString(LongObjectId i) {
		return i != null ? i.name() : ZEROID_STR;
	}

	/**
	 * Compare two object identifier byte sequences for equality.
	 *
	 * @param firstBuffer
	 *            the first buffer to compare against. Must have at least 32
	 *            bytes from position fi through the end of the buffer.
	 * @param fi
	 *            first offset within firstBuffer to begin testing.
	 * @param secondBuffer
	 *            the second buffer to compare against. Must have at least 32
	 *            bytes from position si through the end of the buffer.
	 * @param si
	 *            first offset within secondBuffer to begin testing.
	 * @return true if the two identifiers are the same.
	 */
	public static boolean equals(final byte[] firstBuffer, final int fi,
			final byte[] secondBuffer, final int si) {
		return firstBuffer[fi] == secondBuffer[si]
				&& firstBuffer[fi + 1] == secondBuffer[si + 1]
				&& firstBuffer[fi + 2] == secondBuffer[si + 2]
				&& firstBuffer[fi + 3] == secondBuffer[si + 3]
				&& firstBuffer[fi + 4] == secondBuffer[si + 4]
				&& firstBuffer[fi + 5] == secondBuffer[si + 5]
				&& firstBuffer[fi + 6] == secondBuffer[si + 6]
				&& firstBuffer[fi + 7] == secondBuffer[si + 7]
				&& firstBuffer[fi + 8] == secondBuffer[si + 8]
				&& firstBuffer[fi + 9] == secondBuffer[si + 9]
				&& firstBuffer[fi + 10] == secondBuffer[si + 10]
				&& firstBuffer[fi + 11] == secondBuffer[si + 11]
				&& firstBuffer[fi + 12] == secondBuffer[si + 12]
				&& firstBuffer[fi + 13] == secondBuffer[si + 13]
				&& firstBuffer[fi + 14] == secondBuffer[si + 14]
				&& firstBuffer[fi + 15] == secondBuffer[si + 15]
				&& firstBuffer[fi + 16] == secondBuffer[si + 16]
				&& firstBuffer[fi + 17] == secondBuffer[si + 17]
				&& firstBuffer[fi + 18] == secondBuffer[si + 18]
				&& firstBuffer[fi + 19] == secondBuffer[si + 19]
				&& firstBuffer[fi + 20] == secondBuffer[si + 20]
				&& firstBuffer[fi + 21] == secondBuffer[si + 21]
				&& firstBuffer[fi + 22] == secondBuffer[si + 22]
				&& firstBuffer[fi + 23] == secondBuffer[si + 23]
				&& firstBuffer[fi + 24] == secondBuffer[si + 24]
				&& firstBuffer[fi + 25] == secondBuffer[si + 25]
				&& firstBuffer[fi + 26] == secondBuffer[si + 26]
				&& firstBuffer[fi + 27] == secondBuffer[si + 27]
				&& firstBuffer[fi + 28] == secondBuffer[si + 28]
				&& firstBuffer[fi + 29] == secondBuffer[si + 29]
				&& firstBuffer[fi + 30] == secondBuffer[si + 30]
				&& firstBuffer[fi + 31] == secondBuffer[si + 31];
	}

	/**
	 * Convert a LongObjectId from raw binary representation.
	 *
	 * @param bs
	 *            the raw byte buffer to read from. At least 32 bytes must be
	 *            available within this byte array.
	 * @return the converted object id.
	 */
	public static final LongObjectId fromRaw(byte[] bs) {
		return fromRaw(bs, 0);
	}

	/**
	 * Convert a LongObjectId from raw binary representation.
	 *
	 * @param bs
	 *            the raw byte buffer to read from. At least 32 bytes after p
	 *            must be available within this byte array.
	 * @param p
	 *            position to read the first byte of data from.
	 * @return the converted object id.
	 */
	public static final LongObjectId fromRaw(byte[] bs, int p) {
		final long a = NB.decodeInt64(bs, p);
		final long b = NB.decodeInt64(bs, p + 8);
		final long c = NB.decodeInt64(bs, p + 16);
		final long d = NB.decodeInt64(bs, p + 24);
		return new LongObjectId(a, b, c, d);
	}

	/**
	 * Convert a LongObjectId from raw binary representation.
	 *
	 * @param is
	 *            the raw long buffer to read from. At least 4 longs must be
	 *            available within this long array.
	 * @return the converted object id.
	 */
	public static final LongObjectId fromRaw(long[] is) {
		return fromRaw(is, 0);
	}

	/**
	 * Convert a LongObjectId from raw binary representation.
	 *
	 * @param is
	 *            the raw long buffer to read from. At least 4 longs after p
	 *            must be available within this long array.
	 * @param p
	 *            position to read the first long of data from.
	 * @return the converted object id.
	 */
	public static final LongObjectId fromRaw(long[] is, int p) {
		return new LongObjectId(is[p], is[p + 1], is[p + 2], is[p + 3]);
	}

	/**
	 * Convert a LongObjectId from hex characters (US-ASCII).
	 *
	 * @param buf
	 *            the US-ASCII buffer to read from. At least 64 bytes after
	 *            offset must be available within this byte array.
	 * @param offset
	 *            position to read the first character from.
	 * @return the converted object id.
	 */
	public static final LongObjectId fromString(byte[] buf, int offset) {
		return fromHexString(buf, offset);
	}

	/**
	 * Convert a LongObjectId from hex characters.
	 *
	 * @param str
	 *            the string to read from. Must be 64 characters long.
	 * @return the converted object id.
	 */
	public static LongObjectId fromString(String str) {
		if (str.length() != Constants.LONG_OBJECT_ID_STRING_LENGTH)
			throw new InvalidLongObjectIdException(str);
		return fromHexString(org.eclipse.jgit.lib.Constants.encodeASCII(str),
				0);
	}

	private static final LongObjectId fromHexString(byte[] bs, int p) {
		try {
			final long a = RawParseUtils.parseHexInt64(bs, p);
			final long b = RawParseUtils.parseHexInt64(bs, p + 16);
			final long c = RawParseUtils.parseHexInt64(bs, p + 32);
			final long d = RawParseUtils.parseHexInt64(bs, p + 48);
			return new LongObjectId(a, b, c, d);
		} catch (ArrayIndexOutOfBoundsException e) {
			InvalidLongObjectIdException e1 = new InvalidLongObjectIdException(
					bs, p, Constants.LONG_OBJECT_ID_STRING_LENGTH);
			e1.initCause(e);
			throw e1;
		}
	}

	LongObjectId(final long new_1, final long new_2, final long new_3,
			final long new_4) {
		w1 = new_1;
		w2 = new_2;
		w3 = new_3;
		w4 = new_4;
	}

	/**
	 * Initialize this instance by copying another existing LongObjectId.
	 * <p>
	 * This constructor is mostly useful for subclasses which want to extend a
	 * LongObjectId with more properties, but initialize from an existing
	 * LongObjectId instance acquired by other means.
	 *
	 * @param src
	 *            another already parsed LongObjectId to copy the value out of.
	 */
	protected LongObjectId(AnyLongObjectId src) {
		w1 = src.w1;
		w2 = src.w2;
		w3 = src.w3;
		w4 = src.w4;
	}

	/** {@inheritDoc} */
	@Override
	public LongObjectId toObjectId() {
		return this;
	}

	private void writeObject(ObjectOutputStream os) throws IOException {
		os.writeLong(w1);
		os.writeLong(w2);
		os.writeLong(w3);
		os.writeLong(w4);
	}

	private void readObject(ObjectInputStream ois) throws IOException {
		w1 = ois.readLong();
		w2 = ois.readLong();
		w3 = ois.readLong();
		w4 = ois.readLong();
	}
}
