/*
 * Copyright (C) 2009-2010, 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.revwalk;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;

import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.junit.Before;
import org.junit.Test;

// Note: Much of this test case is broken as it depends upon
// the graph applying topological sorting *before* doing merge
// simplification.  It also depends upon a difference between
// full history and non-full history for a path, something we
// don't quite yet have a distiction for in JGit.
//
public class RevWalkPathFilter6012Test extends RevWalkTestCase {
	private static final String pA = "pA", pF = "pF", pE = "pE";

	private RevCommit a, b, c, d, e, f, g, h, i;

	private HashMap<RevCommit, String> byName;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();

		// Test graph was stolen from git-core t6012-rev-list-simplify
		// (by Junio C Hamano in 65347030590bcc251a9ff2ed96487a0f1b9e9fa8)
		//
		final RevBlob zF = blob("zF");
		final RevBlob zH = blob("zH");
		final RevBlob zI = blob("zI");
		final RevBlob zS = blob("zS");
		final RevBlob zY = blob("zY");

		a = commit(tree(file(pF, zH)));
		b = commit(tree(file(pF, zI)), a);
		c = commit(tree(file(pF, zI)), a);
		d = commit(tree(file(pA, zS), file(pF, zI)), c);
		parseBody(d);
		e = commit(d.getTree(), d, b);
		f = commit(tree(file(pA, zS), file(pE, zY), file(pF, zI)), e);
		parseBody(f);
		g = commit(tree(file(pE, zY), file(pF, zI)), b);
		h = commit(f.getTree(), g, f);
		i = commit(tree(file(pA, zS), file(pE, zY), file(pF, zF)), h);

		byName = new HashMap<>();
		for (Field z : RevWalkPathFilter6012Test.class.getDeclaredFields()) {
			if (z.getType() == RevCommit.class)
				byName.put((RevCommit) z.get(this), z.getName());
		}
	}

	protected void check(RevCommit... order) throws Exception {
		markStart(i);
		final StringBuilder act = new StringBuilder();
		for (RevCommit z : rw) {
			final String name = byName.get(z);
			assertNotNull(name);
			act.append(name);
			act.append(' ');
		}
		final StringBuilder exp = new StringBuilder();
		for (RevCommit z : order) {
			final String name = byName.get(z);
			assertNotNull(name);
			exp.append(name);
			exp.append(' ');
		}
		assertEquals(exp.toString(), act.toString());
	}

	protected void filter(String path) {
		rw.setTreeFilter(AndTreeFilter.create(PathFilterGroup
				.createFromStrings(Collections.singleton(path)),
				TreeFilter.ANY_DIFF));
	}

	@Test
	public void test1() throws Exception {
		// TODO --full-history
		check(i, h, g, f, e, d, c, b, a);
	}

	@Test
	public void test2() throws Exception {
		// TODO --full-history
		filter(pF);
		// TODO fix broken test
		// check(i, h, e, c, b, a);
	}

	@Test
	public void test3() throws Exception {
		// TODO --full-history
		rw.sort(RevSort.TOPO);
		filter(pF);
		// TODO fix broken test
		// check(i, h, e, c, b, a);
	}

	@Test
	public void test4() throws Exception {
		// TODO --full-history
		rw.sort(RevSort.COMMIT_TIME_DESC);
		filter(pF);
		// TODO fix broken test
		// check(i, h, e, c, b, a);
	}

	@Test
	public void test5() throws Exception {
		// TODO --simplify-merges
		filter(pF);
		// TODO fix broken test
		// check(i, e, c, b, a);
	}

	@Test
	public void test6() throws Exception {
		filter(pF);
		check(i, b, a);
	}

	@Test
	public void test7() throws Exception {
		rw.sort(RevSort.TOPO);
		filter(pF);
		check(i, b, a);
	}
}
