/*
 * Copyright (C) 2008-2009, Google Inc. 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 java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE;
import static org.eclipse.jgit.lib.FileMode.SYMLINK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;

import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.util.RawParseUtils;
import org.junit.Before;
import org.junit.Test;

public class CanonicalTreeParserTest {
	private final CanonicalTreeParser ctp = new CanonicalTreeParser();

	private final FileMode m644 = FileMode.REGULAR_FILE;

	private final FileMode mt = FileMode.TREE;

	private final ObjectId hash_a = ObjectId
			.fromString("6b9c715d21d5486e59083fb6071566aa6ecd4d42");

	private final ObjectId hash_foo = ObjectId
			.fromString("a213e8e25bb2442326e86cbfb9ef56319f482869");

	private final ObjectId hash_sometree = ObjectId
			.fromString("daf4bdb0d7bb24319810fe0e73aa317663448c93");

	private byte[] tree1;

	private byte[] tree2;

	private byte[] tree3;

	@Before
	public void setUp() throws Exception {
		tree1 = mktree(entry(m644, "a", hash_a));
		tree2 = mktree(entry(m644, "a", hash_a), entry(m644, "foo", hash_foo));
		tree3 = mktree(entry(m644, "a", hash_a), entry(mt, "b_sometree",
				hash_sometree), entry(m644, "foo", hash_foo));
	}

	private static byte[] mktree(byte[]... data) throws Exception {
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		for (byte[] e : data)
			out.write(e);
		return out.toByteArray();
	}

	private static byte[] entry(final FileMode mode, final String name,
			final ObjectId id) throws Exception {
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		mode.copyTo(out);
		out.write(' ');
		out.write(Constants.encode(name));
		out.write(0);
		id.copyRawTo(out);
		return out.toByteArray();
	}

	private String path() {
		return RawParseUtils.decode(UTF_8, ctp.path,
				ctp.pathOffset, ctp.pathLen);
	}

	@Test
	public void testEmptyTree_AtEOF() throws Exception {
		ctp.reset(new byte[0]);
		assertTrue(ctp.eof());
	}

	@Test
	public void testOneEntry_Forward() throws Exception {
		ctp.reset(tree1);

		assertTrue(ctp.first());
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());

		ctp.next(1);
		assertFalse(ctp.first());
		assertTrue(ctp.eof());
	}

	@Test
	public void testTwoEntries_ForwardOneAtATime() throws Exception {
		ctp.reset(tree2);

		assertTrue(ctp.first());
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());

		ctp.next(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("foo", path());
		assertEquals(hash_foo, ctp.getEntryObjectId());

		ctp.next(1);
		assertFalse(ctp.first());
		assertTrue(ctp.eof());
	}

	@Test
	public void testOneEntry_Seek1IsEOF() throws Exception {
		ctp.reset(tree1);
		ctp.next(1);
		assertTrue(ctp.eof());
	}

	@Test
	public void testTwoEntries_Seek2IsEOF() throws Exception {
		ctp.reset(tree2);
		ctp.next(2);
		assertTrue(ctp.eof());
	}

	@Test
	public void testThreeEntries_Seek3IsEOF() throws Exception {
		ctp.reset(tree3);
		ctp.next(3);
		assertTrue(ctp.eof());
	}

	@Test
	public void testThreeEntries_Seek2() throws Exception {
		ctp.reset(tree3);

		ctp.next(2);
		assertFalse(ctp.eof());
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("foo", path());
		assertEquals(hash_foo, ctp.getEntryObjectId());

		ctp.next(1);
		assertTrue(ctp.eof());
	}

	@Test
	public void testOneEntry_Backwards() throws Exception {
		ctp.reset(tree1);
		ctp.next(1);
		assertFalse(ctp.first());
		assertTrue(ctp.eof());

		ctp.back(1);
		assertTrue(ctp.first());
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());
	}

	@Test
	public void testTwoEntries_BackwardsOneAtATime() throws Exception {
		ctp.reset(tree2);
		ctp.next(2);
		assertTrue(ctp.eof());

		ctp.back(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("foo", path());
		assertEquals(hash_foo, ctp.getEntryObjectId());

		ctp.back(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());
	}

	@Test
	public void testTwoEntries_BackwardsTwo() throws Exception {
		ctp.reset(tree2);
		ctp.next(2);
		assertTrue(ctp.eof());

		ctp.back(2);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());

		ctp.next(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("foo", path());
		assertEquals(hash_foo, ctp.getEntryObjectId());

		ctp.next(1);
		assertTrue(ctp.eof());
	}

	@Test
	public void testThreeEntries_BackwardsTwo() throws Exception {
		ctp.reset(tree3);
		ctp.next(3);
		assertTrue(ctp.eof());

		ctp.back(2);
		assertFalse(ctp.eof());
		assertEquals(mt.getBits(), ctp.mode);
		assertEquals("b_sometree", path());
		assertEquals(hash_sometree, ctp.getEntryObjectId());

		ctp.next(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("foo", path());
		assertEquals(hash_foo, ctp.getEntryObjectId());

		ctp.next(1);
		assertTrue(ctp.eof());
	}

	@Test
	public void testBackwards_ConfusingPathName() throws Exception {
		final String aVeryConfusingName = "confusing 644 entry 755 and others";
		ctp.reset(mktree(entry(m644, "a", hash_a), entry(mt, aVeryConfusingName,
				hash_sometree), entry(m644, "foo", hash_foo)));
		ctp.next(3);
		assertTrue(ctp.eof());

		ctp.back(2);
		assertFalse(ctp.eof());
		assertEquals(mt.getBits(), ctp.mode);
		assertEquals(aVeryConfusingName, path());
		assertEquals(hash_sometree, ctp.getEntryObjectId());

		ctp.back(1);
		assertFalse(ctp.eof());
		assertEquals(m644.getBits(), ctp.mode);
		assertEquals("a", path());
		assertEquals(hash_a, ctp.getEntryObjectId());
	}

	@Test
	public void testBackwords_Prebuilts1() throws Exception {
		// What is interesting about this test is the ObjectId for the
		// "darwin-x86" path entry ends in an octal digit (37 == '7').
		// Thus when scanning backwards we could over scan and consume
		// part of the SHA-1, and miss the path terminator.
		//
		final ObjectId common = ObjectId
				.fromString("af7bf97cb9bce3f60f1d651a0ef862e9447dd8bc");
		final ObjectId darwinx86 = ObjectId
				.fromString("e927f7398240f78face99e1a738dac54ef738e37");
		final ObjectId linuxx86 = ObjectId
				.fromString("ac08dd97120c7cb7d06e98cd5b152011183baf21");
		final ObjectId windows = ObjectId
				.fromString("6c4c64c221a022bb973165192cca4812033479df");

		ctp.reset(mktree(entry(mt, "common", common), entry(mt, "darwin-x86",
				darwinx86), entry(mt, "linux-x86", linuxx86), entry(mt,
				"windows", windows)));
		ctp.next(3);
		assertEquals("windows", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(windows, ctp.getEntryObjectId());

		ctp.back(1);
		assertEquals("linux-x86", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(linuxx86, ctp.getEntryObjectId());

		ctp.next(1);
		assertEquals("windows", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(windows, ctp.getEntryObjectId());
	}

	@Test
	public void testBackwords_Prebuilts2() throws Exception {
		// What is interesting about this test is the ObjectId for the
		// "darwin-x86" path entry ends in an octal digit (37 == '7').
		// Thus when scanning backwards we could over scan and consume
		// part of the SHA-1, and miss the path terminator.
		//
		final ObjectId common = ObjectId
				.fromString("af7bf97cb9bce3f60f1d651a0ef862e9447dd8bc");
		final ObjectId darwinx86 = ObjectId
				.fromString("0000000000000000000000000000000000000037");
		final ObjectId linuxx86 = ObjectId
				.fromString("ac08dd97120c7cb7d06e98cd5b152011183baf21");
		final ObjectId windows = ObjectId
				.fromString("6c4c64c221a022bb973165192cca4812033479df");

		ctp.reset(mktree(entry(mt, "common", common), entry(mt, "darwin-x86",
				darwinx86), entry(mt, "linux-x86", linuxx86), entry(mt,
				"windows", windows)));
		ctp.next(3);
		assertEquals("windows", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(windows, ctp.getEntryObjectId());

		ctp.back(1);
		assertEquals("linux-x86", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(linuxx86, ctp.getEntryObjectId());

		ctp.next(1);
		assertEquals("windows", ctp.getEntryPathString());
		assertSame(mt, ctp.getEntryFileMode());
		assertEquals(windows, ctp.getEntryObjectId());
	}

	@Test
	public void testFreakingHugePathName() throws Exception {
		final int n = AbstractTreeIterator.DEFAULT_PATH_SIZE * 4;
		final StringBuilder b = new StringBuilder(n);
		for (int i = 0; i < n; i++)
			b.append('q');
		final String name = b.toString();
		ctp.reset(entry(m644, name, hash_a));
		assertFalse(ctp.eof());
		assertEquals(name, RawParseUtils.decode(UTF_8, ctp.path,
				ctp.pathOffset, ctp.pathLen));
	}

	@Test
	public void testFindAttributesWhenFirst() throws CorruptObjectException {
		TreeFormatter tree = new TreeFormatter();
		tree.append(".gitattributes", REGULAR_FILE, hash_a);
		ctp.reset(tree.toByteArray());

		assertTrue(ctp.findFile(".gitattributes"));
		assertEquals(REGULAR_FILE.getBits(), ctp.getEntryRawMode());
		assertEquals(".gitattributes", ctp.getEntryPathString());
		assertEquals(hash_a, ctp.getEntryObjectId());
	}

	@Test
	public void testFindAttributesWhenSecond() throws CorruptObjectException {
		TreeFormatter tree = new TreeFormatter();
		tree.append(".config", SYMLINK, hash_a);
		tree.append(".gitattributes", REGULAR_FILE, hash_foo);
		ctp.reset(tree.toByteArray());

		assertTrue(ctp.findFile(".gitattributes"));
		assertEquals(REGULAR_FILE.getBits(), ctp.getEntryRawMode());
		assertEquals(".gitattributes", ctp.getEntryPathString());
		assertEquals(hash_foo, ctp.getEntryObjectId());
	}

	@Test
	public void testFindAttributesWhenMissing() throws CorruptObjectException {
		TreeFormatter tree = new TreeFormatter();
		tree.append("src", REGULAR_FILE, hash_a);
		tree.append("zoo", REGULAR_FILE, hash_foo);
		ctp.reset(tree.toByteArray());

		assertFalse(ctp.findFile(".gitattributes"));
		assertEquals(11, ctp.idOffset()); // Did not walk the entire tree.
		assertEquals("src", ctp.getEntryPathString());
	}
}
