/*
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> 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.lib;

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

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.InvalidObjectIdException;
import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.RawParseUtils;

/**
 * A SHA-1 abstraction.
 */
public class ObjectId extends AnyObjectId implements Serializable {
	private static final long serialVersionUID = 1L;

	private static final ObjectId ZEROID;

	private static final String ZEROID_STR;

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

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

	/**
	 * Test a string of characters to verify it is a hex format.
	 * <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 ObjectId.
	 */
	public static final boolean isId(@Nullable String id) {
		if (id == null) {
			return false;
		}
		if (id.length() != Constants.OBJECT_ID_STRING_LENGTH)
			return false;
		try {
			for (int i = 0; i < Constants.OBJECT_ID_STRING_LENGTH; i++) {
				RawParseUtils.parseHexInt4((byte) id.charAt(i));
			}
			return true;
		} catch (ArrayIndexOutOfBoundsException e) {
			return false;
		}
	}

	/**
	 * Convert an ObjectId 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(ObjectId 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 20
	 *            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 20
	 *            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];
	}

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

	/**
	 * Convert an ObjectId from raw binary representation.
	 *
	 * @param bs
	 *            the raw byte buffer to read from. At least 20 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 ObjectId fromRaw(byte[] bs, int p) {
		final int a = NB.decodeInt32(bs, p);
		final int b = NB.decodeInt32(bs, p + 4);
		final int c = NB.decodeInt32(bs, p + 8);
		final int d = NB.decodeInt32(bs, p + 12);
		final int e = NB.decodeInt32(bs, p + 16);
		return new ObjectId(a, b, c, d, e);
	}

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

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

	/**
	 * Convert an ObjectId from hex characters (US-ASCII).
	 *
	 * @param buf
	 *            the US-ASCII buffer to read from. At least 40 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 ObjectId fromString(byte[] buf, int offset) {
		return fromHexString(buf, offset);
	}

	/**
	 * Convert an ObjectId from hex characters.
	 *
	 * @param str
	 *            the string to read from. Must be 40 characters long.
	 * @return the converted object id.
	 */
	public static ObjectId fromString(String str) {
		if (str.length() != Constants.OBJECT_ID_STRING_LENGTH) {
			throw new InvalidObjectIdException(str);
		}
		return fromHexString(Constants.encodeASCII(str), 0);
	}

	private static final ObjectId fromHexString(byte[] bs, int p) {
		try {
			final int a = RawParseUtils.parseHexInt32(bs, p);
			final int b = RawParseUtils.parseHexInt32(bs, p + 8);
			final int c = RawParseUtils.parseHexInt32(bs, p + 16);
			final int d = RawParseUtils.parseHexInt32(bs, p + 24);
			final int e = RawParseUtils.parseHexInt32(bs, p + 32);
			return new ObjectId(a, b, c, d, e);
		} catch (ArrayIndexOutOfBoundsException e) {
			InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
					Constants.OBJECT_ID_STRING_LENGTH);
			e1.initCause(e);
			throw e1;
		}
	}

	/**
	 * Construct an ObjectId from 160 bits provided in 5 words.
	 *
	 * @param new_1
	 *            an int
	 * @param new_2
	 *            an int
	 * @param new_3
	 *            an int
	 * @param new_4
	 *            an int
	 * @param new_5
	 *            an int
	 * @since 4.7
	 */
	public ObjectId(int new_1, int new_2, int new_3, int new_4, int new_5) {
		w1 = new_1;
		w2 = new_2;
		w3 = new_3;
		w4 = new_4;
		w5 = new_5;
	}

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

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

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

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