/*
 * 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.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 e1) {
			throw new InvalidLongObjectIdException(bs, p,
					Constants.LONG_OBJECT_ID_STRING_LENGTH);
		}
	}

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