/*
 * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com> 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.api;

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

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.RebaseResult.Status;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.junit.Before;
import org.junit.Test;

public class PullCommandWithRebaseTest extends RepositoryTestCase {
	/** Second Test repository */
	protected Repository dbTarget;

	private Git source;

	private Git target;

	private File sourceFile;

	private File targetFile;

	@Test
	public void testPullFastForward() throws Exception {
		PullResult res = target.pull().call();
		// nothing to update since we don't have different data yet
		assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
		assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());

		assertFileContentsEqual(targetFile, "Hello world");

		// change the source file
		writeToFile(sourceFile, "Another change");
		source.add().addFilepattern("SomeFile.txt").call();
		source.commit().setMessage("Some change in remote").call();

		res = target.pull().call();

		assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty());
		assertEquals(Status.FAST_FORWARD, res.getRebaseResult().getStatus());
		assertFileContentsEqual(targetFile, "Another change");
		assertEquals(RepositoryState.SAFE, target.getRepository()
				.getRepositoryState());

		res = target.pull().call();
		assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
	}

	@Test
	public void testPullFastForwardWithBranchInSource() throws Exception {
		PullResult res = target.pull().call();
		// nothing to update since we don't have different data yet
		assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
		assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());

		assertFileContentsEqual(targetFile, "Hello world");

		// change the source file
		writeToFile(sourceFile, "Another change\n\n\n\nFoo");
		source.add().addFilepattern("SomeFile.txt").call();
		RevCommit initialCommit = source.commit()
				.setMessage("Some change in remote").call();

		// modify the source file in a branch
		createBranch(initialCommit, "refs/heads/side");
		checkoutBranch("refs/heads/side");
		writeToFile(sourceFile, "Another change\n\n\n\nBoo");
		source.add().addFilepattern("SomeFile.txt").call();
		RevCommit sideCommit = source.commit()
				.setMessage("Some change in remote").call();

		// modify the source file on master
		checkoutBranch("refs/heads/master");
		writeToFile(sourceFile, "More change\n\n\n\nFoo");
		source.add().addFilepattern("SomeFile.txt").call();
		source.commit().setMessage("Some change in remote").call();

		// merge side into master
		MergeResult result = source.merge().include(sideCommit.getId())
				.setStrategy(MergeStrategy.RESOLVE).call();
		assertEquals(MergeStatus.MERGED, result.getMergeStatus());

	}

	@Test
	public void testPullFastForwardDetachedHead() throws Exception {
		Repository repository = source.getRepository();
		writeToFile(sourceFile, "2nd commit");
		source.add().addFilepattern("SomeFile.txt").call();
		source.commit().setMessage("2nd commit").call();

		try (RevWalk revWalk = new RevWalk(repository)) {
			// git checkout HEAD^
			String initialBranch = repository.getBranch();
			Ref initialRef = repository.findRef(Constants.HEAD);
			RevCommit initialCommit = revWalk
					.parseCommit(initialRef.getObjectId());
			assertEquals("this test need linear history", 1,
					initialCommit.getParentCount());
			source.checkout().setName(initialCommit.getParent(0).getName())
					.call();
			assertFalse("expected detached HEAD",
					repository.getFullBranch().startsWith(Constants.R_HEADS));

			// change and commit another file
			File otherFile = new File(sourceFile.getParentFile(),
					System.currentTimeMillis() + ".tst");
			writeToFile(otherFile, "other 2nd commit");
			source.add().addFilepattern(otherFile.getName()).call();
			RevCommit newCommit = source.commit().setMessage("other 2nd commit")
					.call();

			// git pull --rebase initialBranch
			source.pull().setRebase(true).setRemote(".")
					.setRemoteBranchName(initialBranch)
					.call();

			assertEquals(RepositoryState.SAFE,
					source.getRepository().getRepositoryState());
			Ref head = source.getRepository().findRef(Constants.HEAD);
			RevCommit headCommit = revWalk.parseCommit(head.getObjectId());

			// HEAD^ == initialCommit, no merge commit
			assertEquals(1, headCommit.getParentCount());
			assertEquals(initialCommit, headCommit.getParent(0));

			// both contributions for both commits are available
			assertFileContentsEqual(sourceFile, "2nd commit");
			assertFileContentsEqual(otherFile, "other 2nd commit");
			// HEAD has same message as rebased commit
			assertEquals(newCommit.getShortMessage(),
					headCommit.getShortMessage());
		}
	}

	@Test
	public void testPullConflict() throws Exception {
		PullResult res = target.pull().call();
		// nothing to update since we don't have different data yet
		assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
		assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());

		assertFileContentsEqual(targetFile, "Hello world");

		// change the source file
		writeToFile(sourceFile, "Source change");
		source.add().addFilepattern("SomeFile.txt").call();
		source.commit().setMessage("Source change in remote").call();

		// change the target file
		writeToFile(targetFile, "Target change");
		target.add().addFilepattern("SomeFile.txt").call();
		target.commit().setMessage("Target change in local").call();

		res = target.pull().call();

		String remoteUri = target
				.getRepository()
				.getConfig()
				.getString(ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
						ConfigConstants.CONFIG_KEY_URL);

		assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty());
		assertEquals(Status.STOPPED, res.getRebaseResult().getStatus());
		String result = "<<<<<<< Upstream, based on branch 'master' of "
				+ remoteUri
				+ "\nSource change\n=======\nTarget change\n>>>>>>> 42453fd Target change in local\n";
		assertFileContentsEqual(targetFile, result);
		assertEquals(RepositoryState.REBASING_MERGE, target
				.getRepository().getRepositoryState());
	}

	@Test
	public void testPullLocalConflict() throws Exception {
		target.branchCreate().setName("basedOnMaster").setStartPoint(
				"refs/heads/master").setUpstreamMode(SetupUpstreamMode.NOTRACK)
				.call();
		StoredConfig config = target.getRepository().getConfig();
		config.setString("branch", "basedOnMaster", "remote", ".");
		config.setString("branch", "basedOnMaster", "merge",
				"refs/heads/master");
		config.setBoolean("branch", "basedOnMaster", "rebase", true);
		config.save();
		target.getRepository().updateRef(Constants.HEAD).link(
				"refs/heads/basedOnMaster");
		PullResult res = target.pull().call();
		// nothing to update since we don't have different data yet
		assertNull(res.getFetchResult());
		assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());

		assertFileContentsEqual(targetFile, "Hello world");

		// change the file in master
		target.getRepository().updateRef(Constants.HEAD).link(
				"refs/heads/master");
		writeToFile(targetFile, "Master change");
		target.add().addFilepattern("SomeFile.txt").call();
		target.commit().setMessage("Source change in master").call();

		// change the file in slave
		target.getRepository().updateRef(Constants.HEAD).link(
				"refs/heads/basedOnMaster");
		writeToFile(targetFile, "Slave change");
		target.add().addFilepattern("SomeFile.txt").call();
		target.commit().setMessage("Source change in based on master").call();

		res = target.pull().call();

		assertNull(res.getFetchResult());
		assertEquals(Status.STOPPED, res.getRebaseResult().getStatus());
		String result = "<<<<<<< Upstream, based on branch 'master' of local repository\n"
				+ "Master change\n=======\nSlave change\n>>>>>>> 4049c9e Source change in based on master\n";
		assertFileContentsEqual(targetFile, result);
		assertEquals(RepositoryState.REBASING_MERGE, target
				.getRepository().getRepositoryState());
	}

    @Test
	public void testPullFastForwardWithLocalCommitAndRebaseFlagSet() throws Exception {
		final String SOURCE_COMMIT_MESSAGE = "Source commit message for rebase flag test";
		final String TARGET_COMMIT_MESSAGE = "Target commit message for rebase flag test";

		assertFalse(SOURCE_COMMIT_MESSAGE.equals(TARGET_COMMIT_MESSAGE));

		final String SOURCE_FILE_CONTENTS = "Source change";
		final String NEW_FILE_CONTENTS = "New file from target";

		// make sure the config for target says we should pull with merge
		// we will override this later with the setRebase method
		StoredConfig targetConfig = dbTarget.getConfig();
		targetConfig.setBoolean("branch", "master", "rebase", false);
		targetConfig.save();

		// create commit in source
		writeToFile(sourceFile, SOURCE_FILE_CONTENTS);
		source.add().addFilepattern(sourceFile.getName()).call();
		source.commit().setMessage(SOURCE_COMMIT_MESSAGE).call();

		// create commit in target, not conflicting with the new commit in source
		File newFile = new File(dbTarget.getWorkTree().getPath() + "/newFile.txt");
		writeToFile(newFile, NEW_FILE_CONTENTS);
		target.add().addFilepattern(newFile.getName()).call();
		target.commit().setMessage(TARGET_COMMIT_MESSAGE).call();

		// verify that rebase is set to false in the config
		assertFalse(targetConfig.getBoolean("branch", "master", "rebase", true));

		// pull with rebase - local commit in target should be on top
		PullResult pullResult = target.pull().setRebase(true).call();

		// make sure pull is considered successful
		assertTrue(pullResult.isSuccessful());

		// verify rebase result is ok
		RebaseResult rebaseResult = pullResult.getRebaseResult();
		assertNotNull(rebaseResult);
		assertNull(rebaseResult.getFailingPaths());
		assertEquals(Status.OK, rebaseResult.getStatus());

		// Get the HEAD and HEAD~1 commits
		Repository targetRepo = target.getRepository();
		try (RevWalk revWalk = new RevWalk(targetRepo)) {
			ObjectId headId = targetRepo.resolve(Constants.HEAD);
			RevCommit root = revWalk.parseCommit(headId);
			revWalk.markStart(root);
			// HEAD
			RevCommit head = revWalk.next();
			// HEAD~1
			RevCommit beforeHead = revWalk.next();

			// verify the commit message on the HEAD commit
			assertEquals(TARGET_COMMIT_MESSAGE, head.getFullMessage());
			// verify the commit just before HEAD
			assertEquals(SOURCE_COMMIT_MESSAGE, beforeHead.getFullMessage());

			// verify file states
			assertFileContentsEqual(sourceFile, SOURCE_FILE_CONTENTS);
			assertFileContentsEqual(newFile, NEW_FILE_CONTENTS);
			// verify repository state
			assertEquals(RepositoryState.SAFE, target
				.getRepository().getRepositoryState());
		}
	}

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		dbTarget = createWorkRepository();
		source = new Git(db);
		target = new Git(dbTarget);

		// put some file in the source repo
		sourceFile = new File(db.getWorkTree(), "SomeFile.txt");
		writeToFile(sourceFile, "Hello world");
		// and commit it
		source.add().addFilepattern("SomeFile.txt").call();
		source.commit().setMessage("Initial commit for source").call();

		// configure the target repo to connect to the source via "origin"
		StoredConfig targetConfig = dbTarget.getConfig();
		targetConfig.setString("branch", "master", "remote", "origin");
		targetConfig
				.setString("branch", "master", "merge", "refs/heads/master");
		RemoteConfig config = new RemoteConfig(targetConfig, "origin");

		config
				.addURI(new URIish(source.getRepository().getWorkTree()
						.getAbsolutePath()));
		config.addFetchRefSpec(new RefSpec(
				"+refs/heads/*:refs/remotes/origin/*"));
		config.update(targetConfig);
		targetConfig.save();

		targetFile = new File(dbTarget.getWorkTree(), "SomeFile.txt");
		// make sure we have the same content
		target.pull().call();
		target.checkout().setStartPoint("refs/remotes/origin/master").setName(
				"master").call();

		targetConfig
				.setString("branch", "master", "merge", "refs/heads/master");
		targetConfig.setBoolean("branch", "master", "rebase", true);
		targetConfig.save();

		assertFileContentsEqual(targetFile, "Hello world");
	}

	private static void writeToFile(File actFile, String string)
			throws IOException {
		try (FileOutputStream fos = new FileOutputStream(actFile)) {
			fos.write(string.getBytes(UTF_8));
		}
	}

	private static void assertFileContentsEqual(File actFile, String string)
			throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] buffer = new byte[100];
		try (FileInputStream fis = new FileInputStream(actFile)) {
			int read = fis.read(buffer);
			while (read > 0) {
				bos.write(buffer, 0, read);
				read = fis.read(buffer);
			}
			String content = new String(bos.toByteArray(), UTF_8);
			assertEquals(string, content);
		}
	}
}
