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

import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.transport.PackedObjectInfo;
import org.eclipse.jgit.util.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class AbbreviationTest extends LocalDiskRepositoryTestCase {
	private FileRepository db;

	private ObjectReader reader;

	private TestRepository<Repository> test;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		db = createBareRepository();
		reader = db.newObjectReader();
		test = new TestRepository<>(db);
	}

	@Override
	@After
	public void tearDown() throws Exception {
		if (reader != null) {
			reader.close();
		}
	}

	@Test
	public void testAbbreviateOnEmptyRepository() throws IOException {
		ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba");

		assertEquals(id.abbreviate(2), reader.abbreviate(id, 2));
		assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
		assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
		assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
		assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));

		assertEquals(AbbreviatedObjectId.fromObjectId(id), //
				reader.abbreviate(id, OBJECT_ID_STRING_LENGTH));

		Collection<ObjectId> matches;

		matches = reader.resolve(reader.abbreviate(id, 8));
		assertNotNull(matches);
		assertEquals(0, matches.size());

		matches = reader.resolve(AbbreviatedObjectId.fromObjectId(id));
		assertNotNull(matches);
		assertEquals(1, matches.size());
		assertEquals(id, matches.iterator().next());
	}

	@Test
	public void testAbbreviateLooseBlob() throws Exception {
		ObjectId id = test.blob("test");

		assertEquals(id.abbreviate(2), reader.abbreviate(id, 2));
		assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
		assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
		assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
		assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));

		Collection<ObjectId> matches = reader.resolve(reader.abbreviate(id, 8));
		assertNotNull(matches);
		assertEquals(1, matches.size());
		assertEquals(id, matches.iterator().next());

		assertEquals(id, db.resolve(reader.abbreviate(id, 8).name()));
	}

	@Test
	public void testAbbreviatePackedBlob() throws Exception {
		RevBlob id = test.blob("test");
		test.branch("master").commit().add("test", id).child();
		test.packAndPrune();
		assertTrue(reader.has(id));

		assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
		assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
		assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
		assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));

		Collection<ObjectId> matches = reader.resolve(reader.abbreviate(id, 8));
		assertNotNull(matches);
		assertEquals(1, matches.size());
		assertEquals(id, matches.iterator().next());

		assertEquals(id, db.resolve(reader.abbreviate(id, 8).name()));
	}

	@Test
	public void testAbbreviateIsActuallyUnique() throws Exception {
		// This test is far more difficult. We have to manually craft
		// an input that contains collisions at a particular prefix,
		// but this is computationally difficult. Instead we force an
		// index file to have what we want.
		//

		ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba");
		byte[] idBuf = toByteArray(id);
		List<PackedObjectInfo> objects = new ArrayList<>();
		for (int i = 0; i < 256; i++) {
			idBuf[9] = (byte) i;
			objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf)));
		}

		String packName = "pack-" + id.name();
		File packDir = db.getObjectDatabase().getPackDirectory();
		File idxFile = new File(packDir, packName + ".idx");
		File packFile = new File(packDir, packName + ".pack");
		FileUtils.mkdir(packDir, true);
		try (OutputStream dst = new BufferedOutputStream(
				new FileOutputStream(idxFile))) {
			PackIndexWriter writer = new PackIndexWriterV2(dst);
			writer.write(objects, new byte[OBJECT_ID_LENGTH]);
		}

		try (FileOutputStream unused = new FileOutputStream(packFile)) {
			// unused
		}

		assertEquals(id.abbreviate(20), reader.abbreviate(id, 2));

		AbbreviatedObjectId abbrev8 = id.abbreviate(8);
		Collection<ObjectId> matches = reader.resolve(abbrev8);
		assertNotNull(matches);
		assertEquals(objects.size(), matches.size());
		for (PackedObjectInfo info : objects)
			assertTrue("contains " + info.name(), matches.contains(info));

		try {
			db.resolve(abbrev8.name());
			fail("did not throw AmbiguousObjectException");
		} catch (AmbiguousObjectException err) {
			assertEquals(abbrev8, err.getAbbreviatedObjectId());
			matches = err.getCandidates();
			assertNotNull(matches);
			assertEquals(objects.size(), matches.size());
			for (PackedObjectInfo info : objects)
				assertTrue("contains " + info.name(), matches.contains(info));
		}

		assertEquals(id, db.resolve(id.abbreviate(20).name()));
	}

	private static ObjectId id(String name) {
		return ObjectId.fromString(name);
	}

	private static byte[] toByteArray(ObjectId id) throws IOException {
		ByteArrayOutputStream buf = new ByteArrayOutputStream(OBJECT_ID_LENGTH);
		id.copyRawTo(buf);
		return buf.toByteArray();
	}
}
