// Copyright (C) 2020 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.plugins.codeowners.acceptance.api;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerConfigSubject.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersIT;
import com.google.gerrit.plugins.codeowners.api.RenameEmailInput;
import com.google.gerrit.plugins.codeowners.api.RenameEmailResultInfo;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigFileUpdateScanner;
import com.google.gerrit.plugins.codeowners.restapi.RenameEmail;
import com.google.inject.Inject;
import java.util.Optional;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Before;
import org.junit.Test;

/**
 * Acceptance test for the {@link com.google.gerrit.plugins.codeowners.restapi.RenameEmail} REST
 * endpoint.
 *
 * <p>Further tests for the {@link com.google.gerrit.plugins.codeowners.restapi.RenameEmail} REST
 * endpoint that require using the REST API are implemented in {@link
 * com.google.gerrit.plugins.codeowners.acceptance.restapi.RenameEmailRestIT}.
 */
public class RenameEmailIT extends AbstractCodeOwnersIT {
  @Inject private AccountOperations accountOperations;
  @Inject private ProjectOperations projectOperations;
  @Inject private RequestScopeOperations requestScopeOperations;

  private CodeOwnerConfigFileUpdateScanner codeOwnerConfigFileUpdateScanner;

  @Before
  public void setup() throws Exception {
    codeOwnerConfigFileUpdateScanner =
        plugin.getSysInjector().getInstance(CodeOwnerConfigFileUpdateScanner.class);
  }

  @Test
  public void oldEmailIsRequired() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.newEmail = "new@example.com";
    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> renameEmail(project, "master", input));
    assertThat(exception).hasMessageThat().isEqualTo("old email is required");
  }

  @Test
  public void newEmailIsRequired() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = "old@example.com";
    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> renameEmail(project, "master", input));
    assertThat(exception).hasMessageThat().isEqualTo("new email is required");
  }

  @Test
  public void oldEmailNotResolvable() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = "unknown@example.com";
    input.newEmail = admin.email();
    UnprocessableEntityException exception =
        assertThrows(
            UnprocessableEntityException.class, () -> renameEmail(project, "master", input));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(String.format("cannot resolve email %s", input.oldEmail));
  }

  @Test
  public void newEmailNotResolvable() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = admin.email();
    input.newEmail = "unknown@example.com";
    UnprocessableEntityException exception =
        assertThrows(
            UnprocessableEntityException.class, () -> renameEmail(project, "master", input));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(String.format("cannot resolve email %s", input.newEmail));
  }

  @Test
  public void emailsMustBelongToSameAccount() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = admin.email();
    input.newEmail = user.email();
    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> renameEmail(project, "master", input));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "emails must belong to the same account"
                    + " (old email %s is owned by account %d, new email %s is owned by account %d)",
                admin.email(), admin.id().get(), user.email(), user.id().get()));
  }

  @Test
  public void oldAndNewEmailMustDiffer() throws Exception {
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = admin.email();
    input.newEmail = admin.email();
    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> renameEmail(project, "master", input));
    assertThat(exception).hasMessageThat().isEqualTo("old and new email must differ");
  }

  @Test
  public void requiresAuthenticatedUser() throws Exception {
    requestScopeOperations.setApiUserAnonymous();
    AuthException authException =
        assertThrows(
            AuthException.class, () -> renameEmail(project, "master", new RenameEmailInput()));
    assertThat(authException).hasMessageThat().contains("Authentication required");
  }

  @Test
  public void renameEmailRequiresDirectPushPermissionsForNonProjectOwner() throws Exception {
    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    AuthException exception =
        assertThrows(AuthException.class, () -> renameEmail(project, "master", input));
    assertThat(exception).hasMessageThat().isEqualTo("not permitted: update on refs/heads/master");
  }

  @Test
  public void renameEmail_noCodeOwnerConfig() throws Exception {
    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNull();
  }

  @Test
  public void renameEmail_noUpdateIfEmailIsNotContainedInCodeOwnerConfigs() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/")
        .addCodeOwnerEmail(admin.email())
        .create();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addCodeOwnerEmail(admin.email())
        .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNull();
  }

  @Test
  public void renameOwnEmailWithDirectPushPermission() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey1 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(admin.email())
            .addCodeOwnerEmail(user.email())
            .create();

    CodeOwnerConfig.Key codeOwnerConfigKey2 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/foo/")
            .addCodeOwnerEmail(user.email())
            .create();

    // grant all users direct push permissions
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
        .update();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());
    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail);
  }

  @Test
  public void renameOtherEmailWithDirectPushPermission() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey1 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(admin.email())
            .addCodeOwnerEmail(user.email())
            .create();

    CodeOwnerConfig.Key codeOwnerConfigKey2 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/foo/")
            .addCodeOwnerEmail(admin.email())
            .create();

    // grant all users direct push permissions
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
        .update();

    // Allow all users to see secondary emails.
    projectOperations
        .project(allProjects)
        .forUpdate()
        .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
        .update();

    String secondaryEmail = "admin-foo@example.com";
    accountOperations.account(admin.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = admin.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, user.email());
    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail);
  }

  @Test
  public void renameOwnEmailAsProjectOwner() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey1 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(admin.email())
            .create();

    CodeOwnerConfig.Key codeOwnerConfigKey2 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/foo/")
            .addCodeOwnerEmail(admin.email())
            .create();

    String secondaryEmail = "admin-foo@example.com";
    accountOperations.account(admin.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = admin.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, user.email());
    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail);
  }

  @Test
  public void renameOtherEmailAsProjectOwner() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey1 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(admin.email())
            .create();

    CodeOwnerConfig.Key codeOwnerConfigKey2 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/foo/")
            .addCodeOwnerEmail(user.email())
            .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());
    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail);
  }

  @Test
  public void renameEmail_callingUserBecomesCommitAuthor() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/")
        .addCodeOwnerEmail(user.email())
        .addCodeOwnerEmail(admin.email())
        .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();
    assertThat(result.commit.author.email).isEqualTo(admin.email());
  }

  @Test
  public void renameEmailWithDefaultCommitMessage() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/")
        .addCodeOwnerEmail(user.email())
        .addCodeOwnerEmail(admin.email())
        .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();
    assertThat(result.commit.message).isEqualTo(RenameEmail.DEFAULT_COMMIT_MESSAGE);
  }

  @Test
  public void renameEmailWithSpecifiedCommitMessage() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/")
        .addCodeOwnerEmail(user.email())
        .addCodeOwnerEmail(admin.email())
        .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    input.message = "Update email with custom message";
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();
    assertThat(result.commit.message).isEqualTo(input.message);
  }

  @Test
  public void renameEmail_specifiedCommitMessageIsTrimmed() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/")
        .addCodeOwnerEmail(user.email())
        .addCodeOwnerEmail(admin.email())
        .create();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    String message = "Update email with custom message";
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    input.message = "  " + message + "\t";
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();
    assertThat(result.commit.message).isEqualTo(message);
  }

  @Test
  public void renameEmail_lineCommentsArePreserved() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(admin.email())
            .create();

    // insert some comments
    codeOwnerConfigFileUpdateScanner.update(
        BranchNameKey.create(project, "master"),
        "Insert comments",
        (codeOwnerConfigFilePath, codeOwnerConfigFileContent) -> {
          StringBuilder b = new StringBuilder();
          // insert comment line at the top of the file
          b.append("# top comment\n");

          Iterable<String> lines = Splitter.on('\n').split(codeOwnerConfigFileContent);
          b.append(Iterables.get(lines, /* position= */ 0) + "\n");

          // insert comment line in the middle of the file
          b.append("# middle comment\n");

          for (String line : Iterables.skip(lines, /* numberToSkip= */ 1)) {
            b.append(line + "\n");
          }

          // insert comment line at the bottom of the file
          b.append("# bottom comment\n");

          return Optional.of(b.toString());
        });

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    renameEmail(project, "master", input);

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());

    // verify that the comments are still present
    String codeOwnerConfigFileContent =
        codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent();
    Iterable<String> lines = Splitter.on('\n').split(codeOwnerConfigFileContent);
    assertThat(Iterables.get(lines, /* position= */ 0)).isEqualTo("# top comment");
    assertThat(Iterables.get(lines, /* position= */ 2)).isEqualTo("# middle comment");
    assertThat(Iterables.get(lines, /* position= */ Iterables.size(lines) - 2))
        .isEqualTo("# bottom comment");
  }

  @Test
  public void renameEmail_inlineCommentsArePreserved() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(admin.email())
            .create();

    // insert some inline comments
    codeOwnerConfigFileUpdateScanner.update(
        BranchNameKey.create(project, "master"),
        "Insert comments",
        (codeOwnerConfigFilePath, codeOwnerConfigFileContent) -> {
          StringBuilder b = new StringBuilder();
          for (String line : Splitter.on('\n').split(codeOwnerConfigFileContent)) {
            if (line.contains(user.email())) {
              b.append(line + "# some comment\n");
              continue;
            }
            if (line.contains(admin.email())) {
              b.append(line + "# other comment\n");
              continue;
            }
            b.append(line + "\n");
          }

          return Optional.of(b.toString());
        });

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    renameEmail(project, "master", input);

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());

    // verify that the inline comments are still present
    String codeOwnerConfigFileContent =
        codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent();
    for (String line : Splitter.on('\n').split(codeOwnerConfigFileContent)) {
      if (line.contains(secondaryEmail)) {
        assertThat(line).endsWith("# some comment");
      } else if (line.contains(admin.email())) {
        assertThat(line).endsWith("# other comment");
      }
    }
  }

  @Test
  public void renameEmail_emailInCommentIsReplaced() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(admin.email())
            .create();

    // insert some comments
    codeOwnerConfigFileUpdateScanner.update(
        BranchNameKey.create(project, "master"),
        "Insert comments",
        (codeOwnerConfigFilePath, codeOwnerConfigFileContent) ->
            Optional.of("# foo " + user.email() + " bar\n" + codeOwnerConfigFileContent));

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    renameEmail(project, "master", input);

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());

    // verify that the comments are still present
    String codeOwnerConfigFileContent =
        codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent();
    assertThat(
            Iterables.get(Splitter.on('\n').split(codeOwnerConfigFileContent), /* position= */ 0))
        .endsWith("# foo " + secondaryEmail + " bar");
  }

  @Test
  public void renameEmail_emailThatContainsEmailToBeReplacedAsSubstringStaysIntact()
      throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    TestAccount otherUser1 =
        accountCreator.create(
            "otherUser1", "foo" + user.email(), "Other User 1", /* displayName= */ null);
    TestAccount otherUser2 =
        accountCreator.create(
            "otherUser2", user.email() + "bar", "Other User 2", /* displayName= */ null);
    TestAccount otherUser3 =
        accountCreator.create(
            "otherUser3", "foo" + user.email() + "bar", "Other User 3", /* displayName= */ null);

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(user.email())
            .addCodeOwnerEmail(otherUser1.email())
            .addCodeOwnerEmail(otherUser2.email())
            .addCodeOwnerEmail(otherUser3.email())
            .create();

    // grant all users direct push permissions
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
        .update();

    String secondaryEmail = "user-new@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(
            secondaryEmail, otherUser1.email(), otherUser2.email(), otherUser3.email());
  }

  @Test
  public void renameEmailDoesNotTouchCodeOwnerConfigsThatDoNotContainTheEmail() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    TestAccount user2 = accountCreator.user2();

    CodeOwnerConfig.Key codeOwnerConfigKey1 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(admin.email())
            .addCodeOwnerEmail(user.email())
            .create();

    // Create a code owner config that doesn't contain the email to be replaced.
    CodeOwnerConfig.Key codeOwnerConfigKey2 =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/foo/")
            .addCodeOwnerEmail(user2.email())
            .create();

    // grant all users direct push permissions
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
        .update();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey1).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());

    // Check that the second code owner config is still intact.
    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey2).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(user2.email());
  }

  @Test
  public void renameEmailDoesNotTouchNonCodeOwnerConfigFiles() throws Exception {
    skipTestIfRenameEmailNotSupportedByCodeOwnersBackend();

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath("/")
            .addCodeOwnerEmail(admin.email())
            .addCodeOwnerEmail(user.email())
            .create();

    // Create non code owner config files.
    String contentFileA = "some content";
    String contentFileB =
        String.format(
            "some content that contains the email %s that is being renamed", user.email());
    try (TestRepository<Repository> testRepo =
        new TestRepository<>(repoManager.openRepository(project))) {
      testRepo.update(
          "master",
          testRepo
              .commit()
              .message("Update project.config from test")
              .parent(projectOperations.project(project).getHead("master"))
              .add("A", contentFileA)
              .add("B", contentFileB));
    }

    // grant all users direct push permissions
    projectOperations
        .project(project)
        .forUpdate()
        .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
        .update();

    String secondaryEmail = "user-foo@example.com";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    requestScopeOperations.setApiUser(user.id());
    RenameEmailInput input = new RenameEmailInput();
    input.oldEmail = user.email();
    input.newEmail = secondaryEmail;
    RenameEmailResultInfo result = renameEmail(project, "master", input);
    assertThat(result.commit).isNotNull();

    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).get())
        .hasCodeOwnerSetsThat()
        .onlyElement()
        .hasCodeOwnersEmailsThat()
        .containsExactly(secondaryEmail, admin.email());

    // Check that the non code owner config files are still intact.
    assertThat(getFileContent(project, "master", "A")).hasValue(contentFileA);
    assertThat(getFileContent(project, "master", "B")).hasValue(contentFileB);
  }

  private RenameEmailResultInfo renameEmail(
      Project.NameKey projectName, String branchName, RenameEmailInput input)
      throws RestApiException {
    return projectCodeOwnersApiFactory
        .project(projectName)
        .branch(branchName)
        .renameEmailInCodeOwnerConfigFiles(input);
  }

  private void skipTestIfRenameEmailNotSupportedByCodeOwnersBackend() {
    // the proto backend doesn't support renaming emails
    assumeThatCodeOwnersBackendIsNotProtoBackend();
  }

  private Optional<String> getFileContent(Project.NameKey project, String branch, String fileName) {
    try (Repository repo = repoManager.openRepository(project);
        RevWalk rw = new RevWalk(repo)) {
      if (!branch.startsWith(Constants.R_REFS)) {
        branch = Constants.R_HEADS + branch;
      }
      Ref ref = repo.exactRef(branch);
      if (ref == null) {
        return Optional.empty();
      }
      RevTree tree = rw.parseTree(ref.getObjectId());
      TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), fileName, tree);
      if (tw == null) {
        return Optional.empty();
      }
      ObjectLoader loader = rw.getObjectReader().open(tw.getObjectId(0));
      String fileContent = new String(loader.getCachedBytes(), UTF_8);
      return Optional.of(fileContent);
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }
}
