/*
 * Copyright (C) 2013, CloudBees, 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.api;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collection;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class DescribeCommandTest extends RepositoryTestCase {

	private Git git;

	@Parameter(0)
	public boolean useAnnotatedTags;

	@Parameter(1)
	public boolean describeUseAllTags;

	@Parameters(name = "git tag -a {0}?-a: with git describe {1}?--tags:")
	public static Collection<Boolean[]> getUseAnnotatedTagsValues() {
		return Arrays.asList(new Boolean[][] { { Boolean.TRUE, Boolean.FALSE },
				{ Boolean.FALSE, Boolean.FALSE },
				{ Boolean.TRUE, Boolean.TRUE },
				{ Boolean.FALSE, Boolean.TRUE } });
	}

	@Override
	public void setUp() throws Exception {
		super.setUp();
		git = new Git(db);
	}

	@Test(expected = RefNotFoundException.class)
	public void noTargetSet() throws Exception {
		git.describe().call();
	}

	@Test
	public void testDescribe() throws Exception {
		ObjectId c1 = modify("aaa");

		ObjectId c2 = modify("bbb");
		tag("alice-t1");

		ObjectId c3 = modify("ccc");
		tag("bob-t2");

		ObjectId c4 = modify("ddd");
		assertNameStartsWith(c4, "3e563c5");

		assertNull(describe(c1));
		assertNull(describe(c1, true));
		assertNull(describe(c1, "a*", "b*", "c*"));
		assertNull(describe(c2, "bob*"));
		assertNull(describe(c2, "?ob*"));

		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("alice-t1", describe(c2));
			assertEquals("alice-t1", describe(c2, "alice*"));
			assertEquals("alice-t1", describe(c2, "a*", "b*", "c*"));

			assertEquals("bob-t2", describe(c3));
			assertEquals("bob-t2-0-g44579eb", describe(c3, true));
			assertEquals("alice-t1-1-g44579eb", describe(c3, "alice*"));
			assertEquals("alice-t1-1-g44579eb", describe(c3, "a??c?-t*"));
			assertEquals("bob-t2", describe(c3, "bob*"));
			assertEquals("bob-t2", describe(c3, "?ob*"));
			assertEquals("bob-t2", describe(c3, "a*", "b*", "c*"));

			// the value verified with git-describe(1)
			assertEquals("bob-t2-1-g3e563c5", describe(c4));
			assertEquals("bob-t2-1-g3e563c5", describe(c4, true));
			assertEquals("alice-t1-2-g3e563c5", describe(c4, "alice*"));
			assertEquals("bob-t2-1-g3e563c5", describe(c4, "bob*"));
			assertEquals("bob-t2-1-g3e563c5", describe(c4, "a*", "b*", "c*"));
		} else {
			assertEquals(null, describe(c2));
			assertEquals(null, describe(c3));
			assertEquals(null, describe(c4));
		}

		// test default target
		if (useAnnotatedTags) {
			assertEquals("bob-t2-1-g3e563c5", git.describe().call());
			assertEquals("bob-t2-1-g3e563c5",
					git.describe().setTags(false).call());
			assertEquals("bob-t2-1-g3e563c5",
					git.describe().setTags(true).call());
		} else {
			assertEquals(null, git.describe().call());
			assertEquals(null, git.describe().setTags(false).call());
			assertEquals("bob-t2-1-g3e563c5",
					git.describe().setTags(true).call());
		}
	}

	@Test
	public void testDescribeMultiMatch() throws Exception {
		ObjectId c1 = modify("aaa");
		tag("v1.0.0");
		tick();
		tag("v1.0.1");
		tick();
		tag("v1.1.0");
		tick();
		tag("v1.1.1");
		ObjectId c2 = modify("bbb");

		if (!useAnnotatedTags && !describeUseAllTags) {
			assertEquals(null, describe(c1));
			assertEquals(null, describe(c2));
			return;
		}

		// Ensure that if we're interested in any tags, we get the most recent tag
		// as per Git behaviour since 1.7.1.1
		if (useAnnotatedTags) {
			assertEquals("v1.1.1", describe(c1));
			assertEquals("v1.1.1-1-gb89dead", describe(c2));
			// Ensure that if we're only interested in one of multiple tags, we get the right match
			assertEquals("v1.0.1", describe(c1, "v1.0*"));
			assertEquals("v1.1.1", describe(c1, "v1.1*"));
			assertEquals("v1.0.1-1-gb89dead", describe(c2, "v1.0*"));
			assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*"));

			// Ensure that ordering of match precedence is preserved as per Git behaviour
			assertEquals("v1.1.1", describe(c1, "v1.0*", "v1.1*"));
			assertEquals("v1.1.1", describe(c1, "v1.1*", "v1.0*"));
			assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.0*", "v1.1*"));
			assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*", "v1.0*"));
		} else {
			// no timestamps so no guarantees on which tag is chosen
			assertNotNull(describe(c1));
			assertNotNull(describe(c2));

			assertNotNull(describe(c1, "v1.0*"));
			assertNotNull(describe(c1, "v1.1*"));
			assertNotNull(describe(c2, "v1.0*"));
			assertNotNull(describe(c2, "v1.1*"));

			// Ensure that ordering of match precedence is preserved as per Git behaviour
			assertNotNull(describe(c1, "v1.0*", "v1.1*"));
			assertNotNull(describe(c1, "v1.1*", "v1.0*"));
			assertNotNull(describe(c2, "v1.0*", "v1.1*"));
			assertNotNull(describe(c2, "v1.1*", "v1.0*"));

		}
	}

	/**
	 * Make sure it finds a tag when not all ancestries include a tag.
	 *
	 * <pre>
	 * c1 -+-&gt; T  -
	 *     |       |
	 *     +-&gt; c3 -+-&gt; c4
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testDescribeBranch() throws Exception {
		ObjectId c1 = modify("aaa");

		ObjectId c2 = modify("bbb");
		tag("t");

		branch("b", c1);

		ObjectId c3 = modify("ccc");

		ObjectId c4 = merge(c2);

		assertNameStartsWith(c4, "119892b");
		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("2 commits: c4 and c3", "t-2-g119892b", describe(c4));
		} else {
			assertEquals(null, describe(c4));
		}
		assertNull(describe(c3));
		assertNull(describe(c3, true));
	}

	private void branch(String name, ObjectId base) throws GitAPIException {
		git.checkout().setCreateBranch(true).setName(name)
				.setStartPoint(base.name()).call();
	}

	/**
	 * When t2 dominates t1, it's clearly preferable to describe by using t2.
	 *
	 * <pre>
	 * t1 -+-&gt; t2  -
	 *     |       |
	 *     +-&gt; c3 -+-&gt; c4
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void t1DominatesT2() throws Exception {
		ObjectId c1 = modify("aaa");
		tag("t1");

		ObjectId c2 = modify("bbb");
		tag("t2");

		branch("b", c1);

		ObjectId c3 = modify("ccc");
		assertNameStartsWith(c3, "0244e7f");

		ObjectId c4 = merge(c2);

		assertNameStartsWith(c4, "119892b");

		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("t2-2-g119892b", describe(c4)); // 2 commits: c4 and c3
			assertEquals("t1-1-g0244e7f", describe(c3));
		} else {
			assertEquals(null, describe(c4));
			assertEquals(null, describe(c3));
		}
	}

	/**
	 * When t1 annotated dominates t2 lightweight tag
	 *
	 * <pre>
	 * t1 -+-> t2  -
	 *     |       |
	 *     +-> c3 -+-> c4
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void t1AnnotatedDominatesT2lightweight() throws Exception {
		ObjectId c1 = modify("aaa");
		tag("t1", useAnnotatedTags);

		ObjectId c2 = modify("bbb");
		tag("t2", false);

		assertNameStartsWith(c2, "3747db3");
		if (useAnnotatedTags && !describeUseAllTags) {
			assertEquals(
					"only annotated tag t1 expected to be used for describe",
					"t1-1-g3747db3", describe(c2)); // 1 commits: t2 overridden
													// by t1
		} else if (!useAnnotatedTags && !describeUseAllTags) {
			assertEquals("no commits to describe expected", null, describe(c2));
		} else {
			assertEquals("lightweight tag t2 expected in describe", "t2",
					describe(c2));
		}

		branch("b", c1);

		ObjectId c3 = modify("ccc");

		assertNameStartsWith(c3, "0244e7f");
		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("t1-1-g0244e7f", describe(c3));
		}

		ObjectId c4 = merge(c2);

		assertNameStartsWith(c4, "119892b");
		if (describeUseAllTags) {
			assertEquals(
					"2 commits for describe commit increment expected since lightweight tag: c4 and c3",
					"t2-2-g119892b", describe(c4)); // 2 commits: c4 and c3
		} else if (!useAnnotatedTags && !describeUseAllTags) {
			assertEquals("no matching commits expected", null, describe(c4));
		} else {
			assertEquals(
					"3 commits for describe commit increment expected since annotated tag: c4 and c3 and c2",
					"t1-3-g119892b", describe(c4)); //
		}
	}

	/**
	 * When t1 is nearer than t2, t2 should be found
	 *
	 * <pre>
	 * c1 -+-&gt; c2 -&gt; t1 -+
	 *     |             |
	 *     +-&gt; t2 -&gt; c3 -+-&gt; c4
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void t1nearerT2() throws Exception {
		ObjectId c1 = modify("aaa");
		modify("bbb");
		ObjectId t1 = modify("ccc");
		tag("t1");

		branch("b", c1);
		modify("ddd");
		tag("t2");
		modify("eee");
		ObjectId c4 = merge(t1);

		assertNameStartsWith(c4, "bb389a4");
		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("t1-3-gbb389a4", describe(c4));
		} else {
			assertEquals(null, describe(c4));
		}
	}

	/**
	 * When t1 and t2 have same depth native git seems to add the depths of both
	 * paths
	 *
	 * <pre>
	 * c1 -+-&gt; t1 -&gt; c2 -+
	 *     |             |
	 *     +-&gt; t2 -&gt; c3 -+-&gt; c4
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void t1sameDepthT2() throws Exception {
		ObjectId c1 = modify("aaa");
		modify("bbb");
		tag("t1");
		ObjectId c2 = modify("ccc");

		branch("b", c1);
		modify("ddd");
		tag("t2");
		modify("eee");
		ObjectId c4 = merge(c2);

		assertNameStartsWith(c4, "bb389a4");
		if (useAnnotatedTags || describeUseAllTags) {
			assertEquals("t2-4-gbb389a4", describe(c4));
		} else {
			assertEquals(null, describe(c4));
		}
	}

	private ObjectId merge(ObjectId c2) throws GitAPIException {
		return git.merge().include(c2).call().getNewHead();
	}

	private ObjectId modify(String content) throws Exception {
		File a = new File(db.getWorkTree(), "a.txt");
		touch(a, content);
		return git.commit().setAll(true).setMessage(content).call().getId();
	}

	private void tag(String tag) throws GitAPIException {
		tag(tag, this.useAnnotatedTags);
	}

	private void tag(String tag, boolean annotatedTag) throws GitAPIException {
		TagCommand tagCommand = git.tag().setName(tag)
				.setAnnotated(annotatedTag);
		if (annotatedTag) {
			tagCommand.setMessage(tag);
		}
		tagCommand.call();
	}

	private static void touch(File f, String contents) throws Exception {
		try (BufferedWriter w = Files.newBufferedWriter(f.toPath(), UTF_8)) {
			w.write(contents);
		}
	}

	private String describe(ObjectId c1, boolean longDesc)
			throws GitAPIException, IOException {
		return git.describe().setTarget(c1).setTags(describeUseAllTags)
				.setLong(longDesc).call();
	}

	private String describe(ObjectId c1) throws GitAPIException, IOException {
		return describe(c1, false);
	}

	private String describe(ObjectId c1, String... patterns) throws Exception {
		return git.describe().setTarget(c1).setTags(describeUseAllTags)
				.setMatch(patterns).call();
	}

	private static void assertNameStartsWith(ObjectId c4, String prefix) {
		assertTrue(c4.name(), c4.name().startsWith(prefix));
	}
}
