/*
 * Copyright (C) 2008-2010, Google Inc.
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * 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.lib;

import static org.eclipse.jgit.util.RawParseUtils.match;
import static org.eclipse.jgit.util.RawParseUtils.nextLF;
import static org.eclipse.jgit.util.RawParseUtils.parseBase10;

import java.text.MessageFormat;

import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.MutableInteger;

/**
 * Verifies that an object is formatted correctly.
 * <p>
 * Verifications made by this class only check that the fields of an object are
 * formatted correctly. The ObjectId checksum of the object is not verified, and
 * connectivity links between objects are also not verified. Its assumed that
 * the caller can provide both of these validations on its own.
 * <p>
 * Instances of this class are not thread safe, but they may be reused to
 * perform multiple object validations.
 */
public class ObjectChecker {
	/** Header "tree " */
	public static final byte[] tree = Constants.encodeASCII("tree ");

	/** Header "parent " */
	public static final byte[] parent = Constants.encodeASCII("parent ");

	/** Header "author " */
	public static final byte[] author = Constants.encodeASCII("author ");

	/** Header "committer " */
	public static final byte[] committer = Constants.encodeASCII("committer ");

	/** Header "encoding " */
	public static final byte[] encoding = Constants.encodeASCII("encoding ");

	/** Header "object " */
	public static final byte[] object = Constants.encodeASCII("object ");

	/** Header "type " */
	public static final byte[] type = Constants.encodeASCII("type ");

	/** Header "tag " */
	public static final byte[] tag = Constants.encodeASCII("tag ");

	/** Header "tagger " */
	public static final byte[] tagger = Constants.encodeASCII("tagger ");

	private final MutableObjectId tempId = new MutableObjectId();

	private final MutableInteger ptrout = new MutableInteger();

	/**
	 * Check an object for parsing errors.
	 *
	 * @param objType
	 *            type of the object. Must be a valid object type code in
	 *            {@link Constants}.
	 * @param raw
	 *            the raw data which comprises the object. This should be in the
	 *            canonical format (that is the format used to generate the
	 *            ObjectId of the object). The array is never modified.
	 * @throws CorruptObjectException
	 *             if an error is identified.
	 */
	public void check(final int objType, final byte[] raw)
			throws CorruptObjectException {
		switch (objType) {
		case Constants.OBJ_COMMIT:
			checkCommit(raw);
			break;
		case Constants.OBJ_TAG:
			checkTag(raw);
			break;
		case Constants.OBJ_TREE:
			checkTree(raw);
			break;
		case Constants.OBJ_BLOB:
			checkBlob(raw);
			break;
		default:
			throw new CorruptObjectException(MessageFormat.format(
					JGitText.get().corruptObjectInvalidType2,
					Integer.valueOf(objType)));
		}
	}

	private int id(final byte[] raw, final int ptr) {
		try {
			tempId.fromString(raw, ptr);
			return ptr + Constants.OBJECT_ID_STRING_LENGTH;
		} catch (IllegalArgumentException e) {
			return -1;
		}
	}

	private int personIdent(final byte[] raw, int ptr) {
		final int emailB = nextLF(raw, ptr, '<');
		if (emailB == ptr || raw[emailB - 1] != '<')
			return -1;

		final int emailE = nextLF(raw, emailB, '>');
		if (emailE == emailB || raw[emailE - 1] != '>')
			return -1;
		if (emailE == raw.length || raw[emailE] != ' ')
			return -1;

		parseBase10(raw, emailE + 1, ptrout); // when
		ptr = ptrout.value;
		if (emailE + 1 == ptr)
			return -1;
		if (ptr == raw.length || raw[ptr] != ' ')
			return -1;

		parseBase10(raw, ptr + 1, ptrout); // tz offset
		if (ptr + 1 == ptrout.value)
			return -1;
		return ptrout.value;
	}

	/**
	 * Check a commit for errors.
	 *
	 * @param raw
	 *            the commit data. The array is never modified.
	 * @throws CorruptObjectException
	 *             if any error was detected.
	 */
	public void checkCommit(final byte[] raw) throws CorruptObjectException {
		int ptr = 0;

		if ((ptr = match(raw, ptr, tree)) < 0)
			throw new CorruptObjectException("no tree header");
		if ((ptr = id(raw, ptr)) < 0 || raw[ptr++] != '\n')
			throw new CorruptObjectException("invalid tree");

		while (match(raw, ptr, parent) >= 0) {
			ptr += parent.length;
			if ((ptr = id(raw, ptr)) < 0 || raw[ptr++] != '\n')
				throw new CorruptObjectException("invalid parent");
		}

		if ((ptr = match(raw, ptr, author)) < 0)
			throw new CorruptObjectException("no author");
		if ((ptr = personIdent(raw, ptr)) < 0 || raw[ptr++] != '\n')
			throw new CorruptObjectException("invalid author");

		if ((ptr = match(raw, ptr, committer)) < 0)
			throw new CorruptObjectException("no committer");
		if ((ptr = personIdent(raw, ptr)) < 0 || raw[ptr++] != '\n')
			throw new CorruptObjectException("invalid committer");
	}

	/**
	 * Check an annotated tag for errors.
	 *
	 * @param raw
	 *            the tag data. The array is never modified.
	 * @throws CorruptObjectException
	 *             if any error was detected.
	 */
	public void checkTag(final byte[] raw) throws CorruptObjectException {
		int ptr = 0;

		if ((ptr = match(raw, ptr, object)) < 0)
			throw new CorruptObjectException("no object header");
		if ((ptr = id(raw, ptr)) < 0 || raw[ptr++] != '\n')
			throw new CorruptObjectException("invalid object");

		if ((ptr = match(raw, ptr, type)) < 0)
			throw new CorruptObjectException("no type header");
		ptr = nextLF(raw, ptr);

		if ((ptr = match(raw, ptr, tag)) < 0)
			throw new CorruptObjectException("no tag header");
		ptr = nextLF(raw, ptr);

		if ((ptr = match(raw, ptr, tagger)) > 0) {
			if ((ptr = personIdent(raw, ptr)) < 0 || raw[ptr++] != '\n')
				throw new CorruptObjectException("invalid tagger");
		}
	}

	private static int lastPathChar(final int mode) {
		return FileMode.TREE.equals(mode) ? '/' : '\0';
	}

	private static int pathCompare(final byte[] raw, int aPos, final int aEnd,
			final int aMode, int bPos, final int bEnd, final int bMode) {
		while (aPos < aEnd && bPos < bEnd) {
			final int cmp = (raw[aPos++] & 0xff) - (raw[bPos++] & 0xff);
			if (cmp != 0)
				return cmp;
		}

		if (aPos < aEnd)
			return (raw[aPos] & 0xff) - lastPathChar(bMode);
		if (bPos < bEnd)
			return lastPathChar(aMode) - (raw[bPos] & 0xff);
		return 0;
	}

	private static boolean duplicateName(final byte[] raw,
			final int thisNamePos, final int thisNameEnd) {
		final int sz = raw.length;
		int nextPtr = thisNameEnd + 1 + Constants.OBJECT_ID_LENGTH;
		for (;;) {
			int nextMode = 0;
			for (;;) {
				if (nextPtr >= sz)
					return false;
				final byte c = raw[nextPtr++];
				if (' ' == c)
					break;
				nextMode <<= 3;
				nextMode += c - '0';
			}

			final int nextNamePos = nextPtr;
			for (;;) {
				if (nextPtr == sz)
					return false;
				final byte c = raw[nextPtr++];
				if (c == 0)
					break;
			}
			if (nextNamePos + 1 == nextPtr)
				return false;

			final int cmp = pathCompare(raw, thisNamePos, thisNameEnd,
					FileMode.TREE.getBits(), nextNamePos, nextPtr - 1, nextMode);
			if (cmp < 0)
				return false;
			else if (cmp == 0)
				return true;

			nextPtr += Constants.OBJECT_ID_LENGTH;
		}
	}

	/**
	 * Check a canonical formatted tree for errors.
	 *
	 * @param raw
	 *            the raw tree data. The array is never modified.
	 * @throws CorruptObjectException
	 *             if any error was detected.
	 */
	public void checkTree(final byte[] raw) throws CorruptObjectException {
		final int sz = raw.length;
		int ptr = 0;
		int lastNameB = 0, lastNameE = 0, lastMode = 0;

		while (ptr < sz) {
			int thisMode = 0;
			for (;;) {
				if (ptr == sz)
					throw new CorruptObjectException("truncated in mode");
				final byte c = raw[ptr++];
				if (' ' == c)
					break;
				if (c < '0' || c > '7')
					throw new CorruptObjectException("invalid mode character");
				if (thisMode == 0 && c == '0')
					throw new CorruptObjectException("mode starts with '0'");
				thisMode <<= 3;
				thisMode += c - '0';
			}

			if (FileMode.fromBits(thisMode).getObjectType() == Constants.OBJ_BAD)
				throw new CorruptObjectException("invalid mode " + thisMode);

			final int thisNameB = ptr;
			for (;;) {
				if (ptr == sz)
					throw new CorruptObjectException("truncated in name");
				final byte c = raw[ptr++];
				if (c == 0)
					break;
				if (c == '/')
					throw new CorruptObjectException("name contains '/'");
			}
			if (thisNameB + 1 == ptr)
				throw new CorruptObjectException("zero length name");
			if (raw[thisNameB] == '.') {
				final int nameLen = (ptr - 1) - thisNameB;
				if (nameLen == 1)
					throw new CorruptObjectException("invalid name '.'");
				if (nameLen == 2 && raw[thisNameB + 1] == '.')
					throw new CorruptObjectException("invalid name '..'");
			}
			if (duplicateName(raw, thisNameB, ptr - 1))
				throw new CorruptObjectException("duplicate entry names");

			if (lastNameB != 0) {
				final int cmp = pathCompare(raw, lastNameB, lastNameE,
						lastMode, thisNameB, ptr - 1, thisMode);
				if (cmp > 0)
					throw new CorruptObjectException("incorrectly sorted");
			}

			lastNameB = thisNameB;
			lastNameE = ptr - 1;
			lastMode = thisMode;

			ptr += Constants.OBJECT_ID_LENGTH;
			if (ptr > sz)
				throw new CorruptObjectException("truncated in object id");
		}
	}

	/**
	 * Check a blob for errors.
	 *
	 * @param raw
	 *            the blob data. The array is never modified.
	 * @throws CorruptObjectException
	 *             if any error was detected.
	 */
	public void checkBlob(final byte[] raw) throws CorruptObjectException {
		// We can always assume the blob is valid.
	}
}
