/*
 * Copyright (C) 2020, Lee Worrall 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.transport;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;

import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.jgit.errors.NoRemoteRepositoryException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.SymbolicRef;
import org.junit.Test;

public class BasePackConnectionTest {

	@Test
	public void testReadAdvertisedRefsShouldThrowExceptionWithOriginalCause() {
		try (FailingBasePackConnection basePackConnection =
				new FailingBasePackConnection()) {
			Exception result = assertThrows(NoRemoteRepositoryException.class,
					basePackConnection::readAdvertisedRefs);
			assertEquals(EOFException.class, result.getCause().getClass());
		}
	}

	@Test
	public void testUpdateWithSymRefsAdds() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new HashMap<>();
		symRefs.put("HEAD", "refs/heads/main");

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertThat(refMap, hasKey("HEAD"));
		final Ref headRef = refMap.get("HEAD");
		assertThat(headRef, instanceOf(SymbolicRef.class));
		final SymbolicRef headSymRef = (SymbolicRef) headRef;
		assertEquals("HEAD", headSymRef.getName());
		assertSame(mainRef, headSymRef.getTarget());
	}

	@Test
	public void testUpdateWithSymRefsReplaces() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("HEAD", new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "HEAD",
				mainRef.getObjectId()));
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new HashMap<>();
		symRefs.put("HEAD", "refs/heads/main");

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertThat(refMap, hasKey("HEAD"));
		final Ref headRef = refMap.get("HEAD");
		assertThat(headRef, instanceOf(SymbolicRef.class));
		final SymbolicRef headSymRef = (SymbolicRef) headRef;
		assertEquals("HEAD", headSymRef.getName());
		assertSame(mainRef, headSymRef.getTarget());
	}

	@Test
	public void testUpdateWithSymRefsWithIndirectsAdds() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
		symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
		symRefs.put("refs/heads/sym1", "refs/heads/main");
		symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertThat(refMap, hasKey("refs/heads/sym1"));
		final Ref sym1Ref = refMap.get("refs/heads/sym1");
		assertThat(sym1Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
		assertEquals("refs/heads/sym1", sym1SymRef.getName());
		assertSame(mainRef, sym1SymRef.getTarget());

		assertThat(refMap, hasKey("refs/heads/sym2"));
		final Ref sym2Ref = refMap.get("refs/heads/sym2");
		assertThat(sym2Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
		assertEquals("refs/heads/sym2", sym2SymRef.getName());
		assertSame(sym1SymRef, sym2SymRef.getTarget());

		assertThat(refMap, hasKey("refs/heads/sym3"));
		final Ref sym3Ref = refMap.get("refs/heads/sym3");
		assertThat(sym3Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
		assertEquals("refs/heads/sym3", sym3SymRef.getName());
		assertSame(sym2SymRef, sym3SymRef.getTarget());
	}

	@Test
	public void testUpdateWithSymRefsWithIndirectsReplaces() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("refs/heads/sym1", new ObjectIdRef.Unpeeled(
				Ref.Storage.LOOSE, "refs/heads/sym1", mainRef.getObjectId()));
		refMap.put("refs/heads/sym2", new ObjectIdRef.Unpeeled(
				Ref.Storage.LOOSE, "refs/heads/sym2", mainRef.getObjectId()));
		refMap.put("refs/heads/sym3", new ObjectIdRef.Unpeeled(
				Ref.Storage.LOOSE, "refs/heads/sym3", mainRef.getObjectId()));
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
		symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
		symRefs.put("refs/heads/sym1", "refs/heads/main");
		symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertThat(refMap, hasKey("refs/heads/sym1"));
		final Ref sym1Ref = refMap.get("refs/heads/sym1");
		assertThat(sym1Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
		assertEquals("refs/heads/sym1", sym1SymRef.getName());
		assertSame(mainRef, sym1SymRef.getTarget());

		assertThat(refMap, hasKey("refs/heads/sym2"));
		final Ref sym2Ref = refMap.get("refs/heads/sym2");
		assertThat(sym2Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
		assertEquals("refs/heads/sym2", sym2SymRef.getName());
		assertSame(sym1SymRef, sym2SymRef.getTarget());

		assertThat(refMap, hasKey("refs/heads/sym3"));
		final Ref sym3Ref = refMap.get("refs/heads/sym3");
		assertThat(sym3Ref, instanceOf(SymbolicRef.class));
		final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
		assertEquals("refs/heads/sym3", sym3SymRef.getName());
		assertSame(sym2SymRef, sym3SymRef.getTarget());
	}

	@Test
	public void testUpdateWithSymRefsIgnoresSelfReference() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new LinkedHashMap<>();
		symRefs.put("refs/heads/sym1", "refs/heads/sym1");

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertEquals(2, refMap.size());
		assertThat(refMap, not(hasKey("refs/heads/sym1")));
	}

	@Test
	public void testUpdateWithSymRefsIgnoreCircularReference() {
		final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
				"refs/heads/main", ObjectId.fromString(
						"0000000000000000000000000000000000000001"));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(mainRef.getName(), mainRef);
		refMap.put("refs/heads/other",
				new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
						ObjectId.fromString(
								"0000000000000000000000000000000000000002")));

		final Map<String, String> symRefs = new LinkedHashMap<>();
		symRefs.put("refs/heads/sym2", "refs/heads/sym1");
		symRefs.put("refs/heads/sym1", "refs/heads/sym2");

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertEquals(2, refMap.size());
		assertThat(refMap, not(hasKey("refs/heads/sym1")));
		assertThat(refMap, not(hasKey("refs/heads/sym2")));
	}

	@Test
	public void testUpdateWithSymRefsFillInHead() {
		final String oidName = "0000000000000000000000000000000000000001";
		final Ref advertised = new ObjectIdRef.PeeledNonTag(Ref.Storage.NETWORK,
				Constants.HEAD, ObjectId.fromString(oidName));

		final Map<String, Ref> refMap = new HashMap<>();
		refMap.put(advertised.getName(), advertised);

		final Map<String, String> symRefs = new HashMap<>();
		symRefs.put("HEAD", "refs/heads/main");

		BasePackConnection.updateWithSymRefs(refMap, symRefs);

		assertThat(refMap, hasKey("HEAD"));
		assertThat(refMap, hasKey("refs/heads/main"));
		final Ref headRef = refMap.get("HEAD");
		final Ref mainRef = refMap.get("refs/heads/main");
		assertThat(headRef, instanceOf(SymbolicRef.class));
		final SymbolicRef headSymRef = (SymbolicRef) headRef;
		assertEquals(Constants.HEAD, headSymRef.getName());
		assertSame(mainRef, headSymRef.getTarget());
		assertEquals(oidName, headRef.getObjectId().name());
		assertEquals(oidName, mainRef.getObjectId().name());
	}

	private static class FailingBasePackConnection extends BasePackConnection {
		FailingBasePackConnection() {
			super(new TransportLocal(new URIish(),
					new java.io.File("")));
			pckIn = new PacketLineIn(new ByteArrayInputStream(new byte[0]));
		}
	}
}
