// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.acceptance.api.change;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_COMMIT;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_FILES;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.patch.DiffUtil.normalizePatchForComparison;
import static com.google.gerrit.server.patch.DiffUtil.removePatchHeader;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.HEAD;

import com.google.common.collect.ImmutableList;
import com.google.common.hash.Hashing;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.accounts.AccountInput;
import com.google.gerrit.extensions.api.changes.ApplyPatchInput;
import com.google.gerrit.extensions.api.changes.ApplyPatchPatchSetInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.GitPerson;
import com.google.gerrit.extensions.common.testing.GitPersonSubject;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.inject.Inject;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.Base64;
import org.junit.Test;

public class ApplyPatchIT extends AbstractDaemonTest {

  private static final String DESTINATION_BRANCH = "destBranch";

  private static final String ADDED_FILE_NAME = "a_new_file.txt";
  private static final String ADDED_FILE_CONTENT = "First added line\nSecond added line";
  private static final String ADDED_FILE_DIFF =
      "diff --git a/a_new_file.txt b/a_new_file.txt\n"
          + "new file mode 100644\n"
          + "--- /dev/null\n"
          + "+++ b/a_new_file.txt\n"
          + "@@ -0,0 +1,2 @@\n"
          + "+First added line\n"
          + "+Second added line\n"
          + "\\ No newline at end of file\n";

  @Inject private ProjectOperations projectOperations;
  @Inject private RequestScopeOperations requestScopeOperations;
  @Inject private ChangeOperations changeOperations;
  @Inject private AccountOperations accountOperations;

  @Test
  public void applyAddedFilePatch_success() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);

    ChangeInfo result = applyPatch(in);

    DiffInfo diff = fetchDiffForFile(result, ADDED_FILE_NAME);
    assertDiffForNewFile(diff, result.currentRevision, ADDED_FILE_NAME, ADDED_FILE_CONTENT);
  }

  @Test
  public void applyAddedFilePatchAfterUpdatingPreferredEmail() throws Exception {
    String emailOne = "email1@example.com";
    Account.Id testUser = accountOperations.newAccount().preferredEmail(emailOne).create();

    // Create change
    Change.Id change = changeOperations.newChange().project(project).owner(testUser).create();

    // Change preferred email for the user
    String emailTwo = "email2@example.com";
    accountOperations.account(testUser).forUpdate().preferredEmail(emailTwo).update();
    requestScopeOperations.setApiUser(testUser);

    // Apply patch
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.responseFormatOptions = ImmutableList.of(CURRENT_REVISION, CURRENT_COMMIT);
    ChangeInfo result = gApi.changes().id(change.get()).applyPatch(in);

    assertThat(result.getCurrentRevision().commit.committer.email).isEqualTo(emailOne);
  }

  private static final String MODIFIED_FILE_NAME = "modified_file.txt";
  private static final String MODIFIED_FILE_ORIGINAL_CONTENT =
      "First original line\nSecond original line";
  private static final String MODIFIED_FILE_NEW_CONTENT = "Modified line\n";
  private static final String MODIFIED_FILE_DIFF =
      "diff --git a/modified_file.txt b/modified_file.txt\n"
          + "--- a/modified_file.txt\n"
          + "+++ b/modified_file.txt\n"
          + "@@ -1,2 +1 @@\n"
          + "-First original line\n"
          + "-Second original line\n"
          + "+Modified line\n";

  @Test
  public void applyPatchWithoutProvidingPatch_badRequest() throws Exception {
    initBaseWithFile(MODIFIED_FILE_NAME, MODIFIED_FILE_ORIGINAL_CONTENT);
    Throwable error = assertThrows(BadRequestException.class, () -> applyPatch(buildInput(null)));
    assertThat(error).hasMessageThat().isEqualTo("patch required");
  }

  @Test
  public void applyModifiedFilePatch_success() throws Exception {
    initBaseWithFile(MODIFIED_FILE_NAME, MODIFIED_FILE_ORIGINAL_CONTENT);
    ApplyPatchPatchSetInput in = buildInput(MODIFIED_FILE_DIFF);

    ChangeInfo result = applyPatch(in);

    DiffInfo diff = fetchDiffForFile(result, MODIFIED_FILE_NAME);
    assertDiffForFullyModifiedFile(
        diff,
        result.currentRevision,
        MODIFIED_FILE_NAME,
        MODIFIED_FILE_ORIGINAL_CONTENT,
        MODIFIED_FILE_NEW_CONTENT);
  }

  @Test
  public void applyDeletedFilePatch_success() throws Exception {
    final String deletedFileName = "deleted_file.txt";
    final String deletedFileOriginalContent = "content to be deleted.\n";
    final String deletedFileDiff =
        "diff --git a/deleted_file.txt b/deleted_file.txt\n"
            + "--- a/deleted_file.txt\n"
            + "+++ /dev/null\n";
    initBaseWithFile(deletedFileName, deletedFileOriginalContent);
    ApplyPatchPatchSetInput in = buildInput(deletedFileDiff);

    ChangeInfo result = applyPatch(in);

    DiffInfo diff = fetchDiffForFile(result, deletedFileName);
    assertDiffForDeletedFile(diff, deletedFileName, deletedFileOriginalContent);
  }

  @Test
  public void applyRenamedFilePatch_success() throws Exception {
    final String renamedFileOriginalName = "renamed_file_origin.txt";
    final String renamedFileNewName = "renamed_file_new.txt";
    final String renamedFileDiff =
        "diff --git a/renamed_file_origin.txt b/renamed_file_new.txt\n"
            + "rename from renamed_file_origin.txt\n"
            + "rename to renamed_file_new.txt\n"
            + "--- a/renamed_file_origin.txt\n"
            + "+++ b/renamed_file_new.txt\n"
            + "@@ -1,2 +1 @@\n"
            + "-First original line\n"
            + "-Second original line\n"
            + "+Modified line\n";
    initBaseWithFile(renamedFileOriginalName, MODIFIED_FILE_ORIGINAL_CONTENT);
    ApplyPatchPatchSetInput in = buildInput(renamedFileDiff);

    ChangeInfo result = applyPatch(in);

    DiffInfo originalFileDiff = fetchDiffForFile(result, renamedFileOriginalName);
    assertDiffForDeletedFile(
        originalFileDiff, renamedFileOriginalName, MODIFIED_FILE_ORIGINAL_CONTENT);
    DiffInfo newFileDiff = fetchDiffForFile(result, renamedFileNewName);
    assertDiffForNewFile(
        newFileDiff, result.currentRevision, renamedFileNewName, MODIFIED_FILE_NEW_CONTENT);
  }

  @Test
  public void applyValidTraditionalPatch_success() throws Exception {
    final String fileName = "file_name.txt";
    final String originalContent = "original line";
    final String newContent = "new line\n";
    final String diff =
        "diff file_name.txt file_name.txt\n"
            + "--- file_name.txt\n"
            + "+++ file_name.txt\n"
            + "@@ -1 +1 @@\n"
            + "-original line\n"
            + "+new line\n";
    initBaseWithFile(fileName, originalContent);
    ApplyPatchPatchSetInput in = buildInput(diff);

    ChangeInfo result = applyPatch(in);

    DiffInfo fileDiff = fetchDiffForFile(result, fileName);
    assertDiffForFullyModifiedFile(
        fileDiff, result.currentRevision, fileName, originalContent, newContent);
  }

  @Test
  public void applyGerritBasedPatchWithSingleFile_success() throws Exception {
    String head = getHead(repo(), HEAD).name();
    createBranchWithRevision(BranchNameKey.create(project, "branch"), head);
    PushOneCommit.Result baseCommit = createChange("Add file", ADDED_FILE_NAME, ADDED_FILE_CONTENT);
    baseCommit.assertOkStatus();
    BinaryResult originalPatch = gApi.changes().id(baseCommit.getChangeId()).current().patch();
    ApplyPatchPatchSetInput in = buildInput(originalPatch.asString());
    createBranchWithRevision(BranchNameKey.create(project, DESTINATION_BRANCH), head);

    ChangeInfo result = applyPatch(in);

    BinaryResult resultPatch = gApi.changes().id(result.id).current().patch();
    assertThat(normalizePatchForComparison(resultPatch))
        .isEqualTo(normalizePatchForComparison(originalPatch));
  }

  @Test
  public void applyGerritBasedPatchWithMultipleFiles_success() throws Exception {
    PushOneCommit.Result commonBaseCommit =
        createChange("File for modification", MODIFIED_FILE_NAME, MODIFIED_FILE_ORIGINAL_CONTENT);
    commonBaseCommit.assertOkStatus();
    String head = getHead(repo(), HEAD).name();
    createBranchWithRevision(BranchNameKey.create(project, "branch"), head);
    PushOneCommit.Result commitToPatch =
        createChange("Add file", ADDED_FILE_NAME, ADDED_FILE_CONTENT);
    amendChange(
        commitToPatch.getChangeId(), "Modify file", MODIFIED_FILE_NAME, MODIFIED_FILE_NEW_CONTENT);
    commitToPatch.assertOkStatus();
    BinaryResult originalPatch = gApi.changes().id(commitToPatch.getChangeId()).current().patch();
    ApplyPatchPatchSetInput in = buildInput(originalPatch.asString());
    createBranchWithRevision(BranchNameKey.create(project, DESTINATION_BRANCH), head);

    ChangeInfo result = applyPatch(in);

    BinaryResult resultPatch = gApi.changes().id(result.id).current().patch();
    assertThat(normalizePatchForComparison(resultPatch))
        .isEqualTo(normalizePatchForComparison(originalPatch));
  }

  @Test
  public void applyGerritBasedPatchUsingRest_success() throws Exception {
    String head = getHead(repo(), HEAD).name();
    createBranchWithRevision(BranchNameKey.create(project, DESTINATION_BRANCH), head);
    PushOneCommit.Result destChange = createChange("refs/for/" + DESTINATION_BRANCH);
    createBranchWithRevision(BranchNameKey.create(project, "branch"), head);
    PushOneCommit.Result baseCommit =
        createChange(testRepo, "branch", "Add file", ADDED_FILE_NAME, ADDED_FILE_CONTENT, "");
    baseCommit.assertOkStatus();
    RestResponse patchResp =
        userRestSession.get("/changes/" + baseCommit.getChangeId() + "/revisions/current/patch");
    patchResp.assertOK();
    String originalPatch = new String(Base64.decode(patchResp.getEntityContent()), UTF_8);
    ApplyPatchPatchSetInput in = buildInput(originalPatch);

    RestResponse resp =
        adminRestSession.post("/changes/" + destChange.getChangeId() + "/patch:apply", in);

    resp.assertOK();
    BinaryResult resultPatch = gApi.changes().id(destChange.getChangeId()).current().patch();
    assertThat(normalizePatchForComparison(resultPatch))
        .isEqualTo(normalizePatchForComparison(originalPatch));
  }

  @Test
  public void applyGerritBasedPatchUsingRestWithEncodedPatch_success() throws Exception {
    String head = getHead(repo(), HEAD).name();
    createBranchWithRevision(BranchNameKey.create(project, DESTINATION_BRANCH), head);
    PushOneCommit.Result destChange = createChange("refs/for/" + DESTINATION_BRANCH);
    createBranchWithRevision(BranchNameKey.create(project, "branch"), head);
    PushOneCommit.Result baseCommit =
        createChange(testRepo, "branch", "Add file", ADDED_FILE_NAME, ADDED_FILE_CONTENT, "");
    baseCommit.assertOkStatus();
    RestResponse patchResp =
        userRestSession.get("/changes/" + baseCommit.getChangeId() + "/revisions/current/patch");
    patchResp.assertOK();
    String originalEncodedPatch = patchResp.getEntityContent();
    String originalDecodedPatch = new String(Base64.decode(patchResp.getEntityContent()), UTF_8);
    ApplyPatchPatchSetInput in = buildInput(originalEncodedPatch);

    RestResponse resp =
        adminRestSession.post("/changes/" + destChange.getChangeId() + "/patch:apply", in);

    resp.assertOK();
    BinaryResult resultPatch = gApi.changes().id(destChange.getChangeId()).current().patch();
    assertThat(normalizePatchForComparison(resultPatch))
        .isEqualTo(normalizePatchForComparison(originalDecodedPatch));
  }

  @Test
  public void applyPatchWithConflict_appendErrorsToCommitMessage() throws Exception {
    initBaseWithFile(MODIFIED_FILE_NAME, "Unexpected base content");
    String patch = ADDED_FILE_DIFF + MODIFIED_FILE_DIFF;
    ApplyPatchPatchSetInput in = buildInput(patch);
    in.commitMessage = "subject";

    ChangeInfo result = applyPatch(in);

    assertThat(gApi.changes().id(result.id).current().commit(false).message)
        .isEqualTo(
            in.commitMessage
                + "\n\nNOTE FOR REVIEWERS - errors occurred while applying the patch."
                + "\nPLEASE REVIEW CAREFULLY.\nErrors:\nError applying patch in "
                + MODIFIED_FILE_NAME
                + ", hunk HunkHeader[1,2->1,1]: Hunk cannot be applied\n\nOriginal patch:\n "
                + removePatchHeader(patch)
                + "\n\nChange-Id: "
                + result.changeId
                + "\n");
    // Error in MODIFIED_FILE should not affect ADDED_FILE results.
    DiffInfo diff = fetchDiffForFile(result, ADDED_FILE_NAME);
    assertDiffForNewFile(diff, result.currentRevision, ADDED_FILE_NAME, ADDED_FILE_CONTENT);
  }

  @Test
  public void applyPatchWithConflict_appendErrorsToCommitMessageWithLargeOriginalPatch()
      throws Exception {
    initBaseWithFile(MODIFIED_FILE_NAME, "Unexpected base content");
    String modifiedFileDiff =
        "diff --git a/modified_file.txt b/modified_file.txt\n"
            + "--- a/modified_file.txt\n"
            + "+++ b/modified_file.txt\n"
            + "@@ -1,2 +1,1001 @@\n"
            + "-First original line\n"
            + "-Second original line\n"
            + "+Modified line\n"
            + "+1000 additional lines\n".repeat(1000);
    String patch = ADDED_FILE_DIFF + modifiedFileDiff;
    ApplyPatchPatchSetInput in = buildInput(patch);
    in.commitMessage = "subject";

    ChangeInfo result = applyPatch(in);

    assertThat(gApi.changes().id(result.id).current().commit(false).message)
        .isEqualTo(
            in.commitMessage
                + "\n\nNOTE FOR REVIEWERS - errors occurred while applying the patch."
                + "\nPLEASE REVIEW CAREFULLY.\nErrors:\nError applying patch in "
                + MODIFIED_FILE_NAME
                + ", hunk HunkHeader[1,2->1,1001]: Hunk cannot be applied\n\nOriginal patch:\n "
                + removePatchHeader(patch).substring(0, 1024)
                + "\n[[[Original patch trimmed due to size. Decoded string size: "
                + removePatchHeader(patch).length()
                + ". Decoded string SHA1: "
                + Hashing.sha1().hashString(removePatchHeader(patch), UTF_8)
                + ".]]]"
                + "\n\nChange-Id: "
                + result.changeId
                + "\n");
    // Error in MODIFIED_FILE should not affect ADDED_FILE results.
    DiffInfo diff = fetchDiffForFile(result, ADDED_FILE_NAME);
    assertDiffForNewFile(diff, result.currentRevision, ADDED_FILE_NAME, ADDED_FILE_CONTENT);
  }

  @Test
  public void applyPatchWithoutAddPatchSetPermissions_fails() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    projectOperations
        .project(allProjects)
        .forUpdate()
        .remove(
            permissionKey(Permission.ADD_PATCH_SET)
                .ref("refs/for/*")
                .group(REGISTERED_USERS)
                .build())
        .update();
    PushOneCommit.Result destChange = createChange("dest change", "a file", "with content");
    // Add-patch is always allowed for the change owner, so we need to use another account.
    requestScopeOperations.setApiUser(accountCreator.user2().id());

    Throwable error =
        assertThrows(
            AuthException.class, () -> gApi.changes().id(destChange.getChangeId()).applyPatch(in));

    assertThat(error).hasMessageThat().contains("patch set");
  }

  @Test
  public void applyPatchWithCustomMessage_success() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.commitMessage = "custom commit message";

    ChangeInfo result = applyPatch(in);

    assertThat(gApi.changes().id(result.id).current().commit(false).message)
        .contains(in.commitMessage);
  }

  @Test
  public void applyPatchWithBaseCommit_success() throws Exception {
    PushOneCommit.Result baseCommit =
        createChange("base commit", MODIFIED_FILE_NAME, MODIFIED_FILE_ORIGINAL_CONTENT);
    baseCommit.assertOkStatus();
    PushOneCommit.Result ignoredCommit =
        createChange("Ignored file modification", MODIFIED_FILE_NAME, "Ignored file modification");
    ignoredCommit.assertOkStatus();
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(MODIFIED_FILE_DIFF);
    in.base = baseCommit.getCommit().getName();

    ChangeInfo result = applyPatch(in);

    assertThat(gApi.changes().id(result.id).current().commit(false).parents.get(0).commit)
        .isEqualTo(in.base);
  }

  @Test
  public void applyPatchWithDefaultAuthor_success() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);

    ChangeInfo result = applyPatch(in);

    GitPerson person = gApi.changes().id(result.id).current().commit(false).author;
    GitPersonSubject.assertThat(person).email().isEqualTo(admin.email());
  }

  @Test
  public void applyPatchWithAuthorOverrideMissingEmail_throwsIllegalArgument() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.author = new AccountInput();
    in.author.name = "name";

    Throwable error = assertThrows(IllegalArgumentException.class, () -> applyPatch(in));

    assertThat(error).hasMessageThat().contains("E-mail");
  }

  @Test
  public void applyPatchWithAuthorOverrideMissingName_throwsIllegalArgument() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.author = new AccountInput();
    in.author.name = null;
    in.author.email = "gerritlessjane@invalid";

    Throwable error = assertThrows(IllegalArgumentException.class, () -> applyPatch(in));

    assertThat(error).hasMessageThat().contains("Name");
  }

  @Test
  public void applyPatchWithAuthorOverride_success() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.author = new AccountInput();
    in.author.email = "gerritlessjane@invalid";
    // This is an email address that doesn't exist as account on the Gerrit server.
    in.author.name = "Gerritless Jane";

    ChangeInfo result = applyPatch(in);

    RevisionApi rApi = gApi.changes().id(result.id).current();
    GitPerson author = rApi.commit(false).author;
    GitPersonSubject.assertThat(author).email().isEqualTo(in.author.email);
    GitPersonSubject.assertThat(author).name().isEqualTo(in.author.name);
    GitPerson committer = rApi.commit(false).committer;
    GitPersonSubject.assertThat(committer).email().isEqualTo(admin.getNameEmail().email());
  }

  @Test
  public void applyPatchWithAuthorWithoutPermissions_fails() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.author = new AccountInput();
    in.author.name = "Jane";
    in.author.email = "jane@invalid";
    projectOperations
        .project(project)
        .forUpdate()
        .add(block(Permission.FORGE_AUTHOR).ref("refs/*").group(REGISTERED_USERS))
        .update();

    Throwable error = assertThrows(ResourceConflictException.class, () -> applyPatch(in));

    assertThat(error).hasMessageThat().contains("forge author");
  }

  @Test
  public void applyPatchWithSelfAsForgedAuthor_success() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.author = new AccountInput();
    in.author.name = admin.fullName();
    in.author.email = admin.email();
    projectOperations
        .project(project)
        .forUpdate()
        .add(block(Permission.FORGE_AUTHOR).ref("refs/*").group(REGISTERED_USERS))
        .update();

    ChangeInfo result = applyPatch(in);

    GitPerson person = gApi.changes().id(result.id).current().commit(false).author;
    GitPersonSubject.assertThat(person).email().isEqualTo(admin.email());
  }

  @Test
  public void applyPatchWithExplicitBase_overrideParentId() throws Exception {
    PushOneCommit.Result inputParent = createChange("Input parent", "file1", "content");
    PushOneCommit.Result parent = createChange("Parent Change", "file2", "content");
    parent.assertOkStatus();
    PushOneCommit.Result dest = createChange("Destination Change", "file3", "content");
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.base = inputParent.getCommit().name();

    gApi.changes().id(dest.getChangeId()).applyPatch(in);

    ChangeInfo result = get(dest.getChangeId(), CURRENT_REVISION, CURRENT_COMMIT);
    assertThat(result.revisions.get(result.currentRevision).commit.parents.get(0).commit)
        .isEqualTo(inputParent.getCommit().name());

    BinaryResult resultPatch = gApi.changes().id(dest.getChangeId()).current().patch();
    assertThat(normalizePatchForComparison(resultPatch))
        .isEqualTo(normalizePatchForComparison(ADDED_FILE_DIFF));
  }

  @Test
  public void applyPatchWithNoExplicitBase_overwritesLatestPatch() throws Exception {
    PushOneCommit.Result dest = createChange("Destination Change", "ps1.txt", "ps1 content");
    RevCommit originalParentCommit = dest.getCommit().getParent(0);
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);

    gApi.changes().id(dest.getChangeId()).applyPatch(in);

    ChangeInfo result = get(dest.getChangeId(), CURRENT_REVISION, CURRENT_COMMIT, CURRENT_FILES);
    assertThat(result.revisions.get(result.currentRevision).commit.parents.get(0).commit)
        .isEqualTo(originalParentCommit.name());
    assertThat(result.revisions.get(result.currentRevision).files.keySet())
        .containsExactly(ADDED_FILE_NAME);
    assertDiffForNewFile(
        fetchDiffForFile(result, ADDED_FILE_NAME),
        result.currentRevision,
        ADDED_FILE_NAME,
        ADDED_FILE_CONTENT);
  }

  @Test
  public void commitMessage_providedMessage() throws Exception {
    final String msg = "custom message";
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.commitMessage = msg;

    ChangeInfo result = applyPatch(in);

    ChangeInfo info = get(result.changeId, CURRENT_REVISION, CURRENT_COMMIT);
    assertThat(info.revisions.get(info.currentRevision).commit.message)
        .isEqualTo(msg + "\n\nChange-Id: " + result.changeId + "\n");
  }

  @Test
  public void commitMessage_providedMessageWithCorrectChangeId() throws Exception {
    initDestBranch();
    String originalChangeId =
        gApi.changes()
            .create(new ChangeInput(project.get(), DESTINATION_BRANCH, "Default commit message"))
            .info()
            .changeId;
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.commitMessage = "custom commit message\n\nChange-Id: " + originalChangeId + "\n";

    ChangeInfo result = gApi.changes().id(originalChangeId).applyPatch(in);

    ChangeInfo info = get(result.changeId, CURRENT_REVISION, CURRENT_COMMIT);
    assertThat(info.revisions.get(info.currentRevision).commit.message).isEqualTo(in.commitMessage);
  }

  @Test
  public void commitMessage_providedMessageWithWrongChangeId() throws Exception {
    initDestBranch();
    String originalChangeId =
        gApi.changes()
            .create(new ChangeInput(project.get(), DESTINATION_BRANCH, "Default commit message"))
            .info()
            .changeId;
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);
    in.commitMessage = "custom commit message\n\nChange-Id: " + "I1234567890" + "\n";

    assertThrows(
        ResourceConflictException.class, () -> gApi.changes().id(originalChangeId).applyPatch(in));
  }

  @Test
  public void commitMessage_defaultMessageAndPatchHeader() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput("Patch header\n" + ADDED_FILE_DIFF);

    ChangeInfo result = applyPatch(in);

    ChangeInfo info = get(result.changeId, CURRENT_REVISION, CURRENT_COMMIT);
    assertThat(info.revisions.get(info.currentRevision).commit.message)
        .isEqualTo("Default commit message\n\nChange-Id: " + result.changeId + "\n");
  }

  @Test
  public void commitMessage_defaultMessageAndNoPatchHeader() throws Exception {
    initDestBranch();
    ApplyPatchPatchSetInput in = buildInput(ADDED_FILE_DIFF);

    ChangeInfo result = applyPatch(in);

    ChangeInfo info = get(result.changeId, CURRENT_REVISION, CURRENT_COMMIT);
    assertThat(info.revisions.get(info.currentRevision).commit.message)
        .isEqualTo("Default commit message\n\nChange-Id: " + result.changeId + "\n");
  }

  @Test
  public void amendCommitWithValidTraditionalPatch_success() throws Exception {
    final String fileName = "file_name.txt";
    final String originalContent = "original line";
    final String newContent = "new line\n";
    final String diff =
        "diff file_name.txt file_name.txt\n"
            + "--- file_name.txt\n"
            + "+++ file_name.txt\n"
            + "@@ -1 +1 @@\n"
            + "-original line\n"
            + "+new line\n";

    PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo, "Test", fileName, "foo");
    PushOneCommit.Result base = push.to("refs/heads/foo");
    base.assertOkStatus();

    PushOneCommit.Result firstPatchSet =
        createChange(
            testRepo, "foo", "Add original file: " + fileName, fileName, originalContent, null);
    firstPatchSet.assertOkStatus();

    ApplyPatchPatchSetInput in = new ApplyPatchPatchSetInput();
    in.patch = new ApplyPatchInput();
    in.patch.patch = diff;
    in.amend = true;
    in.responseFormatOptions =
        ImmutableList.of(ListChangesOption.CURRENT_REVISION, ListChangesOption.CURRENT_COMMIT);

    ChangeInfo result = gApi.changes().id(firstPatchSet.getChangeId()).applyPatch(in);

    // Parent of patch set 2 = parent of patch set 1, so we actually amended
    assertThat(result.revisions.get(result.currentRevision).commit.parents.get(0).commit)
        .isEqualTo(base.getCommit().getId().getName());
    DiffInfo fileDiff = gApi.changes().id(result.id).current().file(fileName).diff();
    assertDiffForFullyModifiedFile(fileDiff, result.currentRevision, fileName, "foo", newContent);
    assertThat(gApi.changes().id(firstPatchSet.getChangeId()).current().commit(false).message)
        .isEqualTo(firstPatchSet.getCommit().getFullMessage());
  }

  @Test
  public void amendCantBeUsedWithBase() throws Exception {
    final String diff =
        "diff file_name.txt file_name.txt\n"
            + "--- file_name.txt\n"
            + "+++ file_name.txt\n"
            + "@@ -1 +1 @@\n"
            + "-original line\n"
            + "+new line\n";
    PushOneCommit.Result change = createChange();
    ApplyPatchPatchSetInput in = new ApplyPatchPatchSetInput();
    in.patch = new ApplyPatchInput();
    in.patch.patch = diff;
    in.amend = true;
    in.base = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";

    BadRequestException thrown =
        assertThrows(
            BadRequestException.class,
            () -> gApi.changes().id(change.getChangeId()).applyPatch(in));
    assertThat(thrown)
        .hasMessageThat()
        .isEqualTo("amend only works with existing revisions. omit base.");
  }

  @Test
  public void amendCommitWithConflict_appendErrorsToCommitMessage() throws Exception {
    final String fileName = "file_name.txt";
    final String originalContent = "original line";
    final String diff =
        "diff file_name.txt file_name.txt\n"
            + "--- file_name.txt\n"
            + "+++ file_name.txt\n"
            + "@@ -1 +1 @@\n"
            + "-xxx line\n"
            + "+new line\n";

    PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo, "Test", fileName, "foo");
    PushOneCommit.Result base = push.to("refs/heads/foo");
    base.assertOkStatus();

    PushOneCommit.Result firstPatchSet =
        createChange(
            testRepo, "foo", "Add original file: " + fileName, fileName, originalContent, null);
    firstPatchSet.assertOkStatus();

    ApplyPatchPatchSetInput in = new ApplyPatchPatchSetInput();
    in.patch = new ApplyPatchInput();
    in.patch.patch = diff;
    in.amend = true;
    in.responseFormatOptions =
        ImmutableList.of(ListChangesOption.CURRENT_REVISION, ListChangesOption.CURRENT_COMMIT);

    ChangeInfo result = gApi.changes().id(firstPatchSet.getChangeId()).applyPatch(in);
    assertThat(gApi.changes().id(result.id).current().commit(false).message)
        .startsWith(
            "Add original file: file_name.txt\n"
                + "\n"
                + "NOTE FOR REVIEWERS - errors occurred while applying the patch.\n"
                + "PLEASE REVIEW CAREFULLY.\n"
                + "Errors:\n"
                + "Error applying patch in file_name.txt, hunk HunkHeader[1,1->1,1]: Hunk cannot be applied\n"
                + "\n"
                + "Original patch:\n"
                + " diff file_name.txt file_name.txt\n"
                + "--- file_name.txt\n"
                + "+++ file_name.txt\n"
                + "@@ -1 +1 @@\n"
                + "-xxx line\n"
                + "+new line");
  }

  @Test
  public void amendCommitWithValidTraditionalPatchEmptyRepo_resourceNotFound() throws Exception {
    final String fileName = "file_name.txt";
    final String originalContent = "original line";
    final String diff =
        "diff file_name.txt file_name.txt\n"
            + "--- file_name.txt\n"
            + "+++ file_name.txt\n"
            + "@@ -1 +1 @@\n"
            + "-original line\n"
            + "+new line\n";

    Project.NameKey emptyProject = projectOperations.newProject().noEmptyCommit().create();
    TestRepository<InMemoryRepository> emptyClone = cloneProject(emptyProject);
    PushOneCommit.Result firstPatchSet =
        createChange(
            emptyClone,
            "master",
            "Add original file: " + fileName,
            fileName,
            originalContent,
            null);
    firstPatchSet.assertOkStatus();

    ApplyPatchPatchSetInput in = new ApplyPatchPatchSetInput();
    in.patch = new ApplyPatchInput();
    in.patch.patch = diff;
    in.amend = true;

    Throwable error =
        assertThrows(
            ResourceNotFoundException.class,
            () -> gApi.changes().id(firstPatchSet.getChangeId()).applyPatch(in));
    assertThat(error).hasMessageThat().contains("Branch refs/heads/master does not exist");
  }

  private void initDestBranch() throws Exception {
    String head = getHead(repo(), HEAD).name();
    createBranchWithRevision(BranchNameKey.create(project, ApplyPatchIT.DESTINATION_BRANCH), head);
  }

  private void initBaseWithFile(String fileName, String fileContent) throws Exception {
    PushOneCommit.Result baseCommit =
        createChange("Add original file: " + fileName, fileName, fileContent);
    baseCommit.assertOkStatus();
    initDestBranch();
  }

  private ApplyPatchPatchSetInput buildInput(String patch) {
    ApplyPatchPatchSetInput in = new ApplyPatchPatchSetInput();
    in.patch = new ApplyPatchInput();
    in.patch.patch = patch;
    return in;
  }

  private ChangeInfo applyPatch(ApplyPatchPatchSetInput input) throws RestApiException {
    input.responseFormatOptions = ImmutableList.of(ListChangesOption.CURRENT_REVISION);
    return gApi.changes()
        .create(new ChangeInput(project.get(), DESTINATION_BRANCH, "Default commit message"))
        .applyPatch(input);
  }

  private DiffInfo fetchDiffForFile(ChangeInfo result, String fileName) throws RestApiException {
    return gApi.changes().id(result.id).current().file(fileName).diff();
  }
}
