// 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.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.gerrit.server.restapi.change.ApplyPatchUtil;
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";

  private static final String CONFLICTING_FILE_NAME = "conflicting_file.txt";
  private static final String CONFLICTING_FILE_ORIGINAL_CONTENT =
      "First original line\nSecond original line";
  private static final String CONFLICTING_FILE_DIFF =
      "diff --git a/conflicting_file.txt b/conflicting_file.txt\n"
          + "--- a/conflicting_file.txt\n"
          + "+++ b/conflicting_file.txt\n"
          + "@@ -1,2 +1 @@\n"
          + "-First original line\n"
          + "-Third original line\n"
          + "+Modified line\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 applyDecodedPatchConsistsOfBase64CharsOnly_success() throws Exception {
    final String deletedFileName = "file_to_be_deleted";
    final String deletedFileOriginalContent =
        "The deletion patch of this file only contain valid Base64 chars.\n"
            + "However, the patch is not Base64-encoded.\n";
    final String deletedFileDiff =
        "diff --git a/file_to_be_deleted b/file_to_be_deleted\n"
            + "--- a/file_to_be_deleted\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 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_createsConflictMarkers() throws Exception {
    initBaseWithFile(CONFLICTING_FILE_NAME, CONFLICTING_FILE_ORIGINAL_CONTENT);
    String patch = CONFLICTING_FILE_DIFF;
    ApplyPatchPatchSetInput in = buildInput(patch);
    in.commitMessage = "subject";
    in.patch.allowConflicts = true;

    ChangeInfo result = applyPatch(in);
    assertThat(
            gApi.changes()
                .id(result.id)
                .current()
                .file("conflicting_file.txt")
                .content()
                .asString())
        .isEqualTo(
            "<<<<<<< HEAD\n"
                + "First original line\n"
                + "Second original line\n"
                + "=======\n"
                + "Modified line\n"
                + ">>>>>>> PATCH");
    assertThat(gApi.changes().id(result.id).current().commit(false).message)
        .contains(
            "ATTENTION: Conflicts occurred while applying the patch.\n"
                + "Please resolve conflict markers.");
    assertThat(result.containsGitConflicts).isTrue();
  }

  @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: "
                + ApplyPatchUtil.sha1(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 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 longCommitMessage_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 =
        "Looooooooooooooooooong 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();
  }
}
