/*
 * Copyright (C) 2008-2010, Google Inc.
 * Copyright (C) 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.treewalk;

import static org.eclipse.jgit.lib.Constants.DOT_GIT_ATTRIBUTES;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
import static org.eclipse.jgit.lib.Constants.TYPE_TREE;
import static org.eclipse.jgit.lib.Constants.encode;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;

import org.eclipse.jgit.attributes.AttributesNode;
import org.eclipse.jgit.attributes.AttributesRule;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;

/**
 * Parses raw Git trees from the canonical semi-text/semi-binary format.
 */
public class CanonicalTreeParser extends AbstractTreeIterator {
	private static final byte[] EMPTY = {};
	private static final byte[] ATTRS = encode(DOT_GIT_ATTRIBUTES);

	private byte[] raw;

	/** First offset within {@link #raw} of the prior entry. */
	private int prevPtr;

	/** First offset within {@link #raw} of the current entry's data. */
	private int currPtr;

	/** Offset one past the current entry (first byte of next entry). */
	private int nextPtr;

	/**
	 * Create a new parser.
	 */
	public CanonicalTreeParser() {
		reset(EMPTY);
	}

	/**
	 * Create a new parser for a tree appearing in a subset of a repository.
	 *
	 * @param prefix
	 *            position of this iterator in the repository tree. The value
	 *            may be null or the empty array to indicate the prefix is the
	 *            root of the repository. A trailing slash ('/') is
	 *            automatically appended if the prefix does not end in '/'.
	 * @param reader
	 *            reader to load the tree data from.
	 * @param treeId
	 *            identity of the tree being parsed; used only in exception
	 *            messages if data corruption is found.
	 * @throws MissingObjectException
	 *             the object supplied is not available from the repository.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             the object supplied as an argument is not actually a tree and
	 *             cannot be parsed as though it were a tree.
	 * @throws java.io.IOException
	 *             a loose object or pack file could not be read.
	 */
	public CanonicalTreeParser(final byte[] prefix, final ObjectReader reader,
			final AnyObjectId treeId) throws IncorrectObjectTypeException,
			IOException {
		super(prefix);
		reset(reader, treeId);
	}

	private CanonicalTreeParser(CanonicalTreeParser p) {
		super(p);
	}

	/**
	 * Get the parent of this tree parser.
	 *
	 * @return the parent of this tree parser.
	 * @deprecated internal use only
	 */
	@Deprecated
	public CanonicalTreeParser getParent() {
		return (CanonicalTreeParser) parent;
	}

	/**
	 * Reset this parser to walk through the given tree data.
	 *
	 * @param treeData
	 *            the raw tree content.
	 */
	public void reset(byte[] treeData) {
		attributesNode = null;
		raw = treeData;
		prevPtr = -1;
		currPtr = 0;
		if (eof())
			nextPtr = 0;
		else
			parseEntry();
	}

	/**
	 * Reset this parser to walk through the given tree.
	 *
	 * @param reader
	 *            reader to use during repository access.
	 * @param id
	 *            identity of the tree being parsed; used only in exception
	 *            messages if data corruption is found.
	 * @return the root level parser.
	 * @throws MissingObjectException
	 *             the object supplied is not available from the repository.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             the object supplied as an argument is not actually a tree and
	 *             cannot be parsed as though it were a tree.
	 * @throws java.io.IOException
	 *             a loose object or pack file could not be read.
	 */
	public CanonicalTreeParser resetRoot(final ObjectReader reader,
			final AnyObjectId id) throws IncorrectObjectTypeException,
			IOException {
		CanonicalTreeParser p = this;
		while (p.parent != null)
			p = (CanonicalTreeParser) p.parent;
		p.reset(reader, id);
		return p;
	}

	/**
	 * Get this iterator, or its parent, if the tree is at eof.
	 *
	 * @return this iterator, or its parent, if the tree is at eof.
	 */
	public CanonicalTreeParser next() {
		CanonicalTreeParser p = this;
		for (;;) {
			if (p.nextPtr == p.raw.length) {
				// This parser has reached EOF, return to the parent.
				if (p.parent == null) {
					p.currPtr = p.nextPtr;
					return p;
				}
				p = (CanonicalTreeParser) p.parent;
				continue;
			}

			p.prevPtr = p.currPtr;
			p.currPtr = p.nextPtr;
			p.parseEntry();
			return p;
		}
	}

	/**
	 * Reset this parser to walk through the given tree.
	 *
	 * @param reader
	 *            reader to use during repository access.
	 * @param id
	 *            identity of the tree being parsed; used only in exception
	 *            messages if data corruption is found.
	 * @throws MissingObjectException
	 *             the object supplied is not available from the repository.
	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
	 *             the object supplied as an argument is not actually a tree and
	 *             cannot be parsed as though it were a tree.
	 * @throws java.io.IOException
	 *             a loose object or pack file could not be read.
	 */
	public void reset(ObjectReader reader, AnyObjectId id)
			throws IncorrectObjectTypeException, IOException {
		reset(reader.open(id, OBJ_TREE).getCachedBytes());
	}

	/** {@inheritDoc} */
	@Override
	public CanonicalTreeParser createSubtreeIterator(final ObjectReader reader,
			final MutableObjectId idBuffer)
			throws IncorrectObjectTypeException, IOException {
		idBuffer.fromRaw(idBuffer(), idOffset());
		if (!FileMode.TREE.equals(mode)) {
			final ObjectId me = idBuffer.toObjectId();
			throw new IncorrectObjectTypeException(me, TYPE_TREE);
		}
		return createSubtreeIterator0(reader, idBuffer);
	}

	/**
	 * Back door to quickly create a subtree iterator for any subtree.
	 * <p>
	 * Don't use this unless you are ObjectWalk. The method is meant to be
	 * called only once the current entry has been identified as a tree and its
	 * identity has been converted into an ObjectId.
	 *
	 * @param reader
	 *            reader to load the tree data from.
	 * @param id
	 *            ObjectId of the tree to open.
	 * @return a new parser that walks over the current subtree.
	 * @throws java.io.IOException
	 *             a loose object or pack file could not be read.
	 */
	public final CanonicalTreeParser createSubtreeIterator0(
			final ObjectReader reader, final AnyObjectId id)
			throws IOException {
		final CanonicalTreeParser p = new CanonicalTreeParser(this);
		p.reset(reader, id);
		return p;
	}

	/** {@inheritDoc} */
	@Override
	public CanonicalTreeParser createSubtreeIterator(ObjectReader reader)
			throws IncorrectObjectTypeException, IOException {
		return createSubtreeIterator(reader, new MutableObjectId());
	}

	/** {@inheritDoc} */
	@Override
	public boolean hasId() {
		return true;
	}

	/** {@inheritDoc} */
	@Override
	public byte[] idBuffer() {
		return raw;
	}

	/** {@inheritDoc} */
	@Override
	public int idOffset() {
		return nextPtr - OBJECT_ID_LENGTH;
	}

	/** {@inheritDoc} */
	@Override
	public void reset() {
		if (!first())
			reset(raw);
	}

	/** {@inheritDoc} */
	@Override
	public boolean first() {
		return currPtr == 0;
	}

	/** {@inheritDoc} */
	@Override
	public boolean eof() {
		return currPtr == raw.length;
	}

	/** {@inheritDoc} */
	@Override
	public void next(int delta) {
		if (delta == 1) {
			// Moving forward one is the most common case.
			//
			prevPtr = currPtr;
			currPtr = nextPtr;
			if (!eof())
				parseEntry();
			return;
		}

		// Fast skip over records, then parse the last one.
		//
		final int end = raw.length;
		int ptr = nextPtr;
		while (--delta > 0 && ptr != end) {
			prevPtr = ptr;
			while (raw[ptr] != 0)
				ptr++;
			ptr += OBJECT_ID_LENGTH + 1;
		}
		if (delta != 0)
			throw new ArrayIndexOutOfBoundsException(delta);
		currPtr = ptr;
		if (!eof())
			parseEntry();
	}

	/** {@inheritDoc} */
	@Override
	public void back(int delta) {
		if (delta == 1 && 0 <= prevPtr) {
			// Moving back one is common in NameTreeWalk, as the average tree
			// won't have D/F type conflicts to study.
			//
			currPtr = prevPtr;
			prevPtr = -1;
			if (!eof())
				parseEntry();
			return;
		} else if (delta <= 0)
			throw new ArrayIndexOutOfBoundsException(delta);

		// Fast skip through the records, from the beginning of the tree.
		// There is no reliable way to read the tree backwards, so we must
		// parse all over again from the beginning. We hold the last "delta"
		// positions in a buffer, so we can find the correct position later.
		//
		final int[] trace = new int[delta + 1];
		Arrays.fill(trace, -1);
		int ptr = 0;
		while (ptr != currPtr) {
			System.arraycopy(trace, 1, trace, 0, delta);
			trace[delta] = ptr;
			while (raw[ptr] != 0)
				ptr++;
			ptr += OBJECT_ID_LENGTH + 1;
		}
		if (trace[1] == -1)
			throw new ArrayIndexOutOfBoundsException(delta);
		prevPtr = trace[0];
		currPtr = trace[1];
		parseEntry();
	}

	private void parseEntry() {
		int ptr = currPtr;
		byte c = raw[ptr++];
		int tmp = c - '0';
		for (;;) {
			c = raw[ptr++];
			if (' ' == c)
				break;
			tmp <<= 3;
			tmp += c - '0';
		}
		mode = tmp;

		tmp = pathOffset;
		for (;; tmp++) {
			c = raw[ptr++];
			if (c == 0) {
				break;
			}
			if (tmp >= path.length) {
				growPath(tmp);
			}
			path[tmp] = c;
		}
		pathLen = tmp;
		nextPtr = ptr + OBJECT_ID_LENGTH;
	}

	/**
	 * Retrieve the {@link org.eclipse.jgit.attributes.AttributesNode} for the
	 * current entry.
	 *
	 * @param reader
	 *            {@link org.eclipse.jgit.lib.ObjectReader} used to parse the
	 *            .gitattributes entry.
	 * @return {@link org.eclipse.jgit.attributes.AttributesNode} for the
	 *         current entry.
	 * @throws java.io.IOException
	 * @since 4.2
	 */
	public AttributesNode getEntryAttributesNode(ObjectReader reader)
			throws IOException {
		if (attributesNode == null) {
			attributesNode = findAttributes(reader);
		}
		return attributesNode.getRules().isEmpty() ? null : attributesNode;
	}

	private AttributesNode findAttributes(ObjectReader reader)
			throws IOException {
		CanonicalTreeParser itr = new CanonicalTreeParser();
		itr.reset(raw);
		if (itr.findFile(ATTRS)) {
			return loadAttributes(reader, itr.getEntryObjectId());
		}
		return noAttributes();
	}

	private static AttributesNode loadAttributes(ObjectReader reader,
			AnyObjectId id) throws IOException {
		AttributesNode r = new AttributesNode();
		try (InputStream in = reader.open(id, OBJ_BLOB).openStream()) {
			r.parse(in);
		}
		return r.getRules().isEmpty() ? noAttributes() : r;
	}

	private static AttributesNode noAttributes() {
		return new AttributesNode(Collections.<AttributesRule> emptyList());
	}
}
