// Copyright (C) 2021 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.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerCheckInfoSubject.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.config.GerritConfig;
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.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersIT;
import com.google.gerrit.plugins.codeowners.acceptance.testsuite.TestPathExpressions;
import com.google.gerrit.plugins.codeowners.api.CodeOwnerCheckInfo;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigImportMode;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigReference;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerResolver;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerSet;
import com.google.gerrit.plugins.codeowners.backend.config.BackendConfig;
import com.google.gerrit.plugins.codeowners.backend.findowners.FindOwnersBackend;
import com.google.gerrit.plugins.codeowners.backend.proto.ProtoBackend;
import com.google.gerrit.plugins.codeowners.restapi.CheckCodeOwnerCapability;
import com.google.gerrit.plugins.codeowners.util.JgitPath;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

/**
 * Acceptance test for the {@link com.google.gerrit.plugins.codeowners.restapi.CheckCodeOwner} REST
 * endpoint.
 */
public class CheckCodeOwnerIT extends AbstractCodeOwnersIT {
  private static final String ROOT_PATH = "/";

  @Inject private RequestScopeOperations requestScopeOperations;
  @Inject private AccountOperations accountOperations;
  @Inject private ProjectOperations projectOperations;
  @Inject @ServerInitiated private Provider<AccountsUpdate> accountsUpdate;
  @Inject private ExternalIdNotes.Factory externalIdNotesFactory;

  private BackendConfig backendConfig;
  private TestPathExpressions testPathExpressions;

  @Before
  public void setUpCodeOwnersPlugin() throws Exception {
    backendConfig = plugin.getSysInjector().getInstance(BackendConfig.class);
    testPathExpressions = plugin.getSysInjector().getInstance(TestPathExpressions.class);
  }

  @Test
  public void requiresEmail() throws Exception {
    BadRequestException exception =
        assertThrows(BadRequestException.class, () -> checkCodeOwner("/", /* email= */ null));
    assertThat(exception).hasMessageThat().isEqualTo("email required");
  }

  @Test
  public void requiresPath() throws Exception {
    BadRequestException exception =
        assertThrows(
            BadRequestException.class, () -> checkCodeOwner(/* path= */ null, user.email()));
    assertThat(exception).hasMessageThat().isEqualTo("path required");
  }

  @Test
  public void requiresCallerToBeAdminOrHaveTheCheckCodeOwnerCapability() throws Exception {
    requestScopeOperations.setApiUser(user.id());
    AuthException authException =
        assertThrows(AuthException.class, () -> checkCodeOwner(ROOT_PATH, user.email()));
    assertThat(authException)
        .hasMessageThat()
        .isEqualTo(
            String.format("%s for plugin code-owners not permitted", CheckCodeOwnerCapability.ID));
  }

  @Test
  public void checkCodeOwner_byAdmin() throws Exception {
    testCheckCodeOwner();
  }

  @Test
  public void checkCodeOwner_byUserThatHasTheCheckCodeOwnerCapability() throws Exception {
    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability("code-owners-" + CheckCodeOwnerCapability.ID).group(REGISTERED_USERS))
        .update();

    requestScopeOperations.setApiUser(user.id());
    testCheckCodeOwner();
  }

  private void testCheckCodeOwner() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsCodeOwners("/foo/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void checkCodeOwnerThatHasCodeOwnershipThroughMultipleFiles() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsRootCodeOwners(codeOwner);
    setAsCodeOwners("/foo/", codeOwner);
    setAsCodeOwners("/foo/bar/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(
            getCodeOwnerConfigFilePath("/foo/bar/"),
            getCodeOwnerConfigFilePath("/foo/"),
            getCodeOwnerConfigFilePath(ROOT_PATH))
        .inOrder();
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/bar/")),
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void checkCodeOwnerWithParentCodeOwnersIgnored() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsRootCodeOwners(codeOwner);

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

    setAsCodeOwners("/foo/bar/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(
            getCodeOwnerConfigFilePath("/foo/bar/"), getCodeOwnerConfigFilePath("/foo/"))
        .inOrder();
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/bar/")),
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            "parent code owners are ignored",
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void checkCodeOwner_secondaryEmail() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    String secondaryEmail = "codeOwnerSecondary@example.com";
    accountOperations
        .account(codeOwner.id())
        .forUpdate()
        .addSecondaryEmail(secondaryEmail)
        .update();

    setAsRootCodeOwner(secondaryEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, secondaryEmail);
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                secondaryEmail, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void checkNonCodeOwner() throws Exception {
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(String.format("resolved to account %s", user.id()));
  }

  @Test
  public void checkNonExistingEmail() throws Exception {
    String nonExistingEmail = "non-exiting@example.com";

    setAsRootCodeOwner(nonExistingEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, nonExistingEmail);
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                nonExistingEmail, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "cannot resolve code owner email %s: no account with this email exists",
                nonExistingEmail));
  }

  @Test
  public void checkAmbiguousExistingEmail() throws Exception {
    String ambiguousEmail = "ambiguous@example.com";

    setAsRootCodeOwner(ambiguousEmail);

    // Add the email to 2 accounts to make it ambiguous.
    addEmail(user.id(), ambiguousEmail);
    addEmail(admin.id(), ambiguousEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, ambiguousEmail);
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                ambiguousEmail, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "cannot resolve code owner email %s: email is ambiguous", ambiguousEmail));
  }

  @Test
  public void checkOrphanedEmail() throws Exception {
    // Create an external ID with an email for a non-existing account.
    String orphanedEmail = "orphaned@example.com";
    Account.Id accountId = Account.id(999999);
    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = externalIdNotesFactory.load(allUsersRepo);
      extIdNotes.upsert(ExternalId.createEmail(accountId, orphanedEmail));
      extIdNotes.commit(md);
    }

    setAsRootCodeOwner(orphanedEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, orphanedEmail);
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                orphanedEmail, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "cannot resolve account %s for email %s: account does not exists",
                accountId, orphanedEmail),
            String.format(
                "cannot resolve code owner email %s: no active account with this email found",
                orphanedEmail));
  }

  @Test
  public void checkInactiveAccount() throws Exception {
    TestAccount inactiveUser =
        accountCreator.create(
            "inactiveUser", "inactiveUser@example.com", "Inactive User", /* displayName= */ null);
    accountOperations.account(inactiveUser.id()).forUpdate().inactive().update();

    setAsRootCodeOwners(inactiveUser);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, inactiveUser.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                inactiveUser.email(), getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "account %s for email %s is inactive", inactiveUser.id(), inactiveUser.email()));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.net")
  public void checkEmailWithAllowedDomain() throws Exception {
    String emailWithAllowedEmailDomain = "foo@example.net";
    TestAccount userWithAllowedEmail =
        accountCreator.create(
            "userWithAllowedEmail",
            emailWithAllowedEmailDomain,
            "User with allowed emil",
            /* displayName= */ null);

    setAsRootCodeOwners(userWithAllowedEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, emailWithAllowedEmailDomain);
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                emailWithAllowedEmailDomain, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "domain %s of email %s is allowed",
                emailWithAllowedEmailDomain.substring(emailWithAllowedEmailDomain.indexOf('@') + 1),
                emailWithAllowedEmailDomain));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.net")
  public void checkEmailWithNonAllowedDomain() throws Exception {
    String emailWithNonAllowedEmailDomain = "foo@example.com";
    TestAccount userWithAllowedEmail =
        accountCreator.create(
            "userWithNonAllowedEmail",
            emailWithNonAllowedEmailDomain,
            "User with non-allowed emil",
            /* displayName= */ null);

    setAsRootCodeOwners(userWithAllowedEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo =
        checkCodeOwner(ROOT_PATH, emailWithNonAllowedEmailDomain);
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                emailWithNonAllowedEmailDomain, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "domain %s of email %s is not allowed",
                emailWithNonAllowedEmailDomain.substring(
                    emailWithNonAllowedEmailDomain.indexOf('@') + 1),
                emailWithNonAllowedEmailDomain));
  }

  @Test
  public void checkAllUsersWildcard() throws Exception {
    CodeOwnerCheckInfo checkCodeOwnerInfo =
        checkCodeOwner(ROOT_PATH, CodeOwnerResolver.ALL_USERS_WILDCARD);
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
  }

  @Test
  public void checkAllUsersWildcard_ownedByAllUsers() throws Exception {
    setAsRootCodeOwner(CodeOwnerResolver.ALL_USERS_WILDCARD);

    CodeOwnerCheckInfo checkCodeOwnerInfo =
        checkCodeOwner(ROOT_PATH, CodeOwnerResolver.ALL_USERS_WILDCARD);
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                CodeOwnerResolver.ALL_USERS_WILDCARD, getCodeOwnerConfigFilePath(ROOT_PATH)));
  }

  @Test
  public void checkDefaultCodeOwner() throws Exception {
    TestAccount defaultCodeOwner =
        accountCreator.create(
            "defaultCodeOwner",
            "defaultCodeOwner@example.com",
            "Default Code Owner",
            /* displayName= */ null);
    setAsDefaultCodeOwners(defaultCodeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, defaultCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo).isDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in default code owner config",
                defaultCodeOwner.email()),
            String.format("resolved to account %s", defaultCodeOwner.id()));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.globalCodeOwner", value = "globalCodeOwner@example.com")
  public void checkGlobalCodeOwner() throws Exception {
    TestAccount globalCodeOwner =
        accountCreator.create(
            "globalCodeOwner",
            "globalCodeOwner@example.com",
            "Global Code Owner",
            /* displayName= */ null);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, globalCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format("found email %s as global code owner", globalCodeOwner.email()),
            String.format("resolved to account %s", globalCodeOwner.id()));
  }

  @Test
  public void checkCodeOwnerForOtherUser() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsCodeOwners("/foo/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email(), user.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("account %s is visible to user %s", codeOwner.id(), user.username()),
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void cannotCheckForNonExistingUser() throws Exception {
    String nonExistingEmail = "non-existing@example.com";
    BadRequestException exception =
        assertThrows(
            BadRequestException.class, () -> checkCodeOwner("/", user.email(), nonExistingEmail));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(String.format("user %s not found", nonExistingEmail));
  }

  @Test
  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  public void checkNonVisibleCodeOwnerForOtherUser() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);

    setAsRootCodeOwners(codeOwner);

    CodeOwnerCheckInfo checkCodeOwnerInfo =
        checkCodeOwner(ROOT_PATH, codeOwner.email(), user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "cannot resolve code owner email %s: account %s is not visible to user %s",
                codeOwner.email(), codeOwner.id(), user.username()));
  }

  @Test
  public void checkNonVisibleCodeOwnerForOtherUser_secondaryEmail() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    String secondaryEmail = "codeOwnerSecondary@example.com";
    accountOperations
        .account(codeOwner.id())
        .forUpdate()
        .addSecondaryEmail(secondaryEmail)
        .update();

    setAsRootCodeOwner(secondaryEmail);

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, secondaryEmail, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath(ROOT_PATH));
    assertThat(checkCodeOwnerInfo).isNotDefaultCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotGlobalCodeOwner();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "found email %s as code owner in %s",
                secondaryEmail, getCodeOwnerConfigFilePath(ROOT_PATH)),
            String.format(
                "cannot resolve code owner email %s: account %s is referenced by secondary email"
                    + " but user %s cannot see secondary emails",
                secondaryEmail, codeOwner.id(), user.username()));
  }

  @Test
  public void debugLogsContainUnresolvedImports() throws Exception {
    skipTestIfImportsNotSupportedByCodeOwnersBackend();

    CodeOwnerConfigReference unresolvableCodeOwnerConfigReferenceCodeOwnerConfigNotFound =
        CodeOwnerConfigReference.create(
            CodeOwnerConfigImportMode.ALL, "non-existing/" + getCodeOwnerConfigFileName());

    CodeOwnerConfigReference unresolvableCodeOwnerConfigReferenceProjectNotFound =
        CodeOwnerConfigReference.builder(
                CodeOwnerConfigImportMode.ALL, getCodeOwnerConfigFileName())
            .setProject(Project.nameKey("non-existing"))
            .build();

    Project.NameKey nonReadableProject =
        projectOperations.newProject().name("non-readable").create();
    ConfigInput configInput = new ConfigInput();
    configInput.state = ProjectState.HIDDEN;
    gApi.projects().name(nonReadableProject.get()).config(configInput);
    CodeOwnerConfigReference unresolvableCodeOwnerConfigReferenceProjectNotReadable =
        CodeOwnerConfigReference.builder(
                CodeOwnerConfigImportMode.ALL, getCodeOwnerConfigFileName())
            .setProject(nonReadableProject)
            .build();

    CodeOwnerConfig.Key codeOwnerConfigKey =
        codeOwnerConfigOperations
            .newCodeOwnerConfig()
            .project(project)
            .branch("master")
            .folderPath(ROOT_PATH)
            .addImport(unresolvableCodeOwnerConfigReferenceCodeOwnerConfigNotFound)
            .addImport(unresolvableCodeOwnerConfigReferenceProjectNotFound)
            .addImport(unresolvableCodeOwnerConfigReferenceProjectNotReadable)
            .create();

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, user.email());
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:%s imports:\n"
                    + "* %s (global import, import mode = ALL)\n"
                    + "  * failed to resolve (code owner config not found)\n"
                    + "* %s:%s (global import, import mode = ALL)\n"
                    + "  * failed to resolve (project not found)\n"
                    + "* %s:%s (global import, import mode = ALL)\n"
                    + "  * failed to resolve (project state doesn't allow read)",
                project,
                "master",
                getCodeOwnerConfigFilePath(codeOwnerConfigKey.folderPath().toString()),
                unresolvableCodeOwnerConfigReferenceCodeOwnerConfigNotFound.filePath(),
                unresolvableCodeOwnerConfigReferenceProjectNotFound.project().get(),
                unresolvableCodeOwnerConfigReferenceProjectNotFound.filePath(),
                unresolvableCodeOwnerConfigReferenceProjectNotReadable.project().get(),
                unresolvableCodeOwnerConfigReferenceProjectNotReadable.filePath()),
            String.format(
                "The import of %s:%s:%s in %s:%s:%s cannot be resolved:"
                    + " code owner config does not exist (revision = %s)",
                project,
                "master",
                JgitPath.of(unresolvableCodeOwnerConfigReferenceCodeOwnerConfigNotFound.filePath())
                    .getAsAbsolutePath(),
                project,
                "master",
                getCodeOwnerConfigFilePath(codeOwnerConfigKey.folderPath().toString()),
                projectOperations.project(project).getHead("master").name()),
            String.format(
                "The import of %s:%s:%s in %s:%s:%s cannot be resolved: project %s not found",
                unresolvableCodeOwnerConfigReferenceProjectNotFound.project().get(),
                "master",
                JgitPath.of(unresolvableCodeOwnerConfigReferenceProjectNotFound.filePath())
                    .getAsAbsolutePath(),
                project,
                "master",
                getCodeOwnerConfigFilePath(codeOwnerConfigKey.folderPath().toString()),
                unresolvableCodeOwnerConfigReferenceProjectNotFound.project().get()),
            String.format(
                "The import of %s:%s:%s in %s:%s:%s cannot be resolved:"
                    + " state of project %s doesn't permit read",
                unresolvableCodeOwnerConfigReferenceProjectNotReadable.project().get(),
                "master",
                JgitPath.of(unresolvableCodeOwnerConfigReferenceProjectNotReadable.filePath())
                    .getAsAbsolutePath(),
                project,
                "master",
                getCodeOwnerConfigFilePath(codeOwnerConfigKey.folderPath().toString()),
                unresolvableCodeOwnerConfigReferenceProjectNotReadable.project().get()));
  }

  @Test
  public void debugLogsContainUnresolvedTransitiveImports() throws Exception {
    skipTestIfImportsNotSupportedByCodeOwnersBackend();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath(ROOT_PATH)
        .addImport(
            CodeOwnerConfigReference.create(
                CodeOwnerConfigImportMode.ALL, "/foo/" + getCodeOwnerConfigFileName()))
        .create();

    CodeOwnerConfigReference unresolvableCodeOwnerConfigReference =
        CodeOwnerConfigReference.create(
            CodeOwnerConfigImportMode.ALL, "non-existing/" + getCodeOwnerConfigFileName());
    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addImport(unresolvableCodeOwnerConfigReference)
        .create();

    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(ROOT_PATH, user.email());
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:%s imports:\n"
                    + "* %s (global import, import mode = ALL)\n"
                    + "  * %s (global import, import mode = ALL)\n"
                    + "    * failed to resolve (code owner config not found)",
                project,
                "master",
                getCodeOwnerConfigFilePath("/"),
                getCodeOwnerConfigFilePath("/foo/"),
                unresolvableCodeOwnerConfigReference.filePath()),
            String.format(
                "The import of %s:%s:%s in %s:%s:%s cannot be resolved:"
                    + " code owner config does not exist (revision = %s)",
                project,
                "master",
                JgitPath.of(unresolvableCodeOwnerConfigReference.filePath()).getAsAbsolutePath(),
                project,
                "master",
                getCodeOwnerConfigFilePath("/foo/"),
                projectOperations.project(project).getHead("master").name()));
  }

  @Test
  public void checkPerFileCodeOwner() throws Exception {
    TestAccount txtOwner =
        accountCreator.create(
            "txtCodeOwner", "txtCodeOwner@example.com", "Txt Code Owner", /* displayName= */ null);
    TestAccount mdOwner =
        accountCreator.create(
            "mdCodeOwner", "mdCodeOwner@example.com", "Md Code Owner", /* displayName= */ null);

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addCodeOwnerSet(
            CodeOwnerSet.builder()
                .addPathExpression(testPathExpressions.matchFileType("txt"))
                .addCodeOwnerEmail(txtOwner.email())
                .build())
        .addCodeOwnerSet(
            CodeOwnerSet.builder()
                .addPathExpression(testPathExpressions.matchFileType("md"))
                .addCodeOwnerEmail(mdOwner.email())
                .build())
        .create();

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, mdOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "per-file code owner set with path expressions [%s] matches",
                testPathExpressions.matchFileType("md")),
            String.format(
                "found email %s as code owner in %s",
                mdOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("resolved to account %s", mdOwner.id()));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatDoNotContainAnyOf(
            String.format(
                "path expressions [%s] matches", testPathExpressions.matchFileType("txt")));
  }

  @Test
  public void checkPerFileCodeOwnerWhenParentCodeOwnersAreIgnored() throws Exception {
    skipTestIfIgnoreParentCodeOwnersNotSupportedByCodeOwnersBackend();

    TestAccount fileCodeOwner =
        accountCreator.create(
            "fileCodeOwner",
            "fileCodeOwner@example.com",
            "File Code Owner",
            /* displayName= */ null);
    TestAccount folderCodeOwner =
        accountCreator.create(
            "folderCodeOwner",
            "folderCodeOwner@example.com",
            "Folder Code Owner",
            /* displayName= */ null);

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addCodeOwnerEmail(folderCodeOwner.email())
        .addCodeOwnerSet(
            CodeOwnerSet.builder()
                .addPathExpression(testPathExpressions.matchFileType("md"))
                .setIgnoreGlobalAndParentCodeOwners()
                .addCodeOwnerEmail(fileCodeOwner.email())
                .build())
        .create();

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, folderCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "per-file code owner set with path expressions [%s] matches",
                testPathExpressions.matchFileType("md")),
            String.format(
                "found matching per-file code owner set (with path expressions = [%s]) that ignores"
                    + " parent code owners, hence ignoring the folder code owners",
                testPathExpressions.matchFileType("md")));

    checkCodeOwnerInfo = checkCodeOwner(path, fileCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "per-file code owner set with path expressions [%s] matches",
                testPathExpressions.matchFileType("md")),
            String.format(
                "found matching per-file code owner set (with path expressions = [%s]) that ignores"
                    + " parent code owners, hence ignoring the folder code owners",
                testPathExpressions.matchFileType("md")),
            String.format(
                "found email %s as code owner in %s",
                fileCodeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("resolved to account %s", fileCodeOwner.id()));
  }

  @Test
  public void checkCodeOwnerFromImportedConfig() throws Exception {
    skipTestIfImportsNotSupportedByCodeOwnersBackend();

    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addImport(
            CodeOwnerConfigReference.create(
                CodeOwnerConfigImportMode.ALL, "/bar/" + getCodeOwnerConfigFileName()))
        .create();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/bar/")
        .addImport(
            CodeOwnerConfigReference.create(
                CodeOwnerConfigImportMode.ALL, "/baz/" + getCodeOwnerConfigFileName()))
        .create();

    setAsCodeOwners("/baz/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:/foo/%s imports:\n"
                    + "* /bar/%s (global import, import mode = ALL)\n"
                    + "  * /baz/%s (global import, import mode = ALL)",
                project,
                "master",
                getCodeOwnerConfigFileName(),
                getCodeOwnerConfigFileName(),
                getCodeOwnerConfigFileName()),
            String.format(
                "found email %s as code owner in %s",
                codeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("resolved to account %s", codeOwner.id()));
  }

  @Test
  public void checkCodeOwnerFromImportedPerFileConfig() throws Exception {
    skipTestIfImportsNotSupportedByCodeOwnersBackend();

    TestAccount mdCodeOwner =
        accountCreator.create(
            "mdCodeOwner", "mdCodeOwner@example.com", "Md Code Owner", /* displayName= */ null);

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .addImport(
            CodeOwnerConfigReference.create(
                CodeOwnerConfigImportMode.ALL, "/bar/" + getCodeOwnerConfigFileName()))
        .create();

    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/bar/")
        .addCodeOwnerSet(
            CodeOwnerSet.builder()
                .addPathExpression(testPathExpressions.matchFileType("md"))
                .addImport(
                    CodeOwnerConfigReference.create(
                        CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY,
                        "/baz/" + getCodeOwnerConfigFileName()))
                .build())
        .create();

    setAsCodeOwners("/baz/", mdCodeOwner);

    // 1. check for mdCodeOwner and path of an md file
    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, mdCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo)
        .hasCodeOwnerConfigFilePathsThat()
        .containsExactly(getCodeOwnerConfigFilePath("/foo/"));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:/foo/%s imports:\n"
                    + "* /bar/%s (global import, import mode = ALL)\n"
                    + "  * per-file code owner set with path expressions [%s] matches\n"
                    + "  * /baz/%s (per-file import, import mode = GLOBAL_CODE_OWNER_SETS_ONLY,"
                    + " path expressions = [%s])",
                project,
                "master",
                getCodeOwnerConfigFileName(),
                getCodeOwnerConfigFileName(),
                testPathExpressions.matchFileType("md"),
                getCodeOwnerConfigFileName(),
                testPathExpressions.matchFileType("md")),
            String.format(
                "found email %s as code owner in %s",
                mdCodeOwner.email(), getCodeOwnerConfigFilePath("/foo/")),
            String.format("resolved to account %s", mdCodeOwner.id()));

    // 2. check for user and path of an md file
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:/foo/%s imports:\n"
                    + "* /bar/%s (global import, import mode = ALL)\n"
                    + "  * per-file code owner set with path expressions [%s] matches\n"
                    + "  * /baz/%s (per-file import, import mode = GLOBAL_CODE_OWNER_SETS_ONLY,"
                    + " path expressions = [%s])",
                project,
                "master",
                getCodeOwnerConfigFileName(),
                getCodeOwnerConfigFileName(),
                testPathExpressions.matchFileType("md"),
                getCodeOwnerConfigFileName(),
                testPathExpressions.matchFileType("md")),
            String.format("resolved to account %s", user.id()));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatDoNotContainAnyOf(String.format("email %s", user.email()));

    // 3. check for mdCodeOwner and path of an txt file
    path = "/foo/bar/baz.txt";
    checkCodeOwnerInfo = checkCodeOwner(path, mdCodeOwner.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isResolvable();
    assertThat(checkCodeOwnerInfo).hasCodeOwnerConfigFilePathsThat().isEmpty();
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatContainAllOf(
            String.format(
                "Code owner config %s:%s:/foo/%s imports:\n"
                    + "* /bar/%s (global import, import mode = ALL)",
                project, "master", getCodeOwnerConfigFileName(), getCodeOwnerConfigFileName()),
            String.format("resolved to account %s", mdCodeOwner.id()));
    assertThat(checkCodeOwnerInfo)
        .hasDebugLogsThatDoNotContainAnyOf(String.format("email %s", mdCodeOwner.email()));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  public void checkFallbackCodeOwner_AllUsers() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsCodeOwners("/foo/", codeOwner);

    // 1. Check for a file to which fallback code owners do not apply because code owners are
    // defined
    String path = "/foo/bar/baz.md";

    // 1a. by a code owner
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 1b. by a non code owner
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 2. Check for a file to which fallback code owners apply because no code owners are defined
    path = "/other/bar/baz.md";
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isFallbackCodeOwner();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "PROJECT_OWNERS")
  public void checkFallbackCodeOwner_ProjectOwners() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsCodeOwners("/foo/", codeOwner);

    // 1. Check for a file to which fallback code owners do not apply because code owners are
    // defined
    String path = "/foo/bar/baz.md";

    // 1a. by a code owner
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 1b. by a project owner
    checkCodeOwnerInfo = checkCodeOwner(path, admin.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 1c. by a non code owner
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 2. Check for a file to which fallback code owners apply because no code owners are defined
    path = "/other/bar/baz.md";

    // 2b. by a project owner
    checkCodeOwnerInfo = checkCodeOwner(path, admin.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isFallbackCodeOwner();

    // 2b. by a non project owner
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  public void noFallbackCodeOwnerIfParentCodeOwnersIgnored() throws Exception {
    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath("/foo/")
        .ignoreParentCodeOwners()
        .create();

    // 1. Check for a file to which parent code owners are ignored
    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();

    // 2. Check for a file to which parent code owners are not ignored
    path = "/other/bar/baz.md";
    checkCodeOwnerInfo = checkCodeOwner(path, user.email());
    assertThat(checkCodeOwnerInfo).isCodeOwner();
    assertThat(checkCodeOwnerInfo).isFallbackCodeOwner();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  public void noFallbackCodeOwnerIfNonVisibleRelevantCodeOwnerExists() throws Exception {
    TestAccount nonVisibleCodeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);

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

    requestScopeOperations.setApiUser(user.id());

    // verify that the account is not visible
    assertThrows(
        ResourceNotFoundException.class, () -> gApi.accounts().id(nonVisibleCodeOwner.id().get()));

    // allow user to call the check code owner REST endpoint
    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability("code-owners-" + CheckCodeOwnerCapability.ID).group(REGISTERED_USERS))
        .update();

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, admin.email());
    assertThat(checkCodeOwnerInfo).isNotCodeOwner();
    assertThat(checkCodeOwnerInfo).isNotFallbackCodeOwner();
  }

  @Test
  public void noEmptyDebugLogs() throws Exception {
    TestAccount codeOwner =
        accountCreator.create(
            "codeOwner", "codeOwner@example.com", "Code Owner", /* displayName= */ null);
    setAsCodeOwners("/foo/", codeOwner);

    String path = "/foo/bar/baz.md";
    CodeOwnerCheckInfo checkCodeOwnerInfo = checkCodeOwner(path, codeOwner.email());
    assertThat(checkCodeOwnerInfo).hasDebugLogsThatDoNotContainAnyOf("");
  }

  private CodeOwnerCheckInfo checkCodeOwner(String path, String email) throws RestApiException {
    return checkCodeOwner(path, email, null);
  }

  private CodeOwnerCheckInfo checkCodeOwner(String path, String email, @Nullable String user)
      throws RestApiException {
    return projectCodeOwnersApiFactory
        .project(project)
        .branch("master")
        .checkCodeOwner()
        .path(path)
        .email(email)
        .user(user)
        .check();
  }

  private String getCodeOwnerConfigFilePath(String folderPath) {
    assertThat(folderPath).startsWith("/");
    assertThat(folderPath).endsWith("/");
    return folderPath + getCodeOwnerConfigFileName();
  }

  private void setAsRootCodeOwner(String email) {
    codeOwnerConfigOperations
        .newCodeOwnerConfig()
        .project(project)
        .branch("master")
        .folderPath(ROOT_PATH)
        .addCodeOwnerEmail(email)
        .create();
  }

  private String getCodeOwnerConfigFileName() {
    CodeOwnerBackend backend = backendConfig.getDefaultBackend();
    if (backend instanceof FindOwnersBackend) {
      return FindOwnersBackend.CODE_OWNER_CONFIG_FILE_NAME;
    } else if (backend instanceof ProtoBackend) {
      return ProtoBackend.CODE_OWNER_CONFIG_FILE_NAME;
    }
    throw new IllegalStateException("unknown code owner backend: " + backend.getClass().getName());
  }

  private void addEmail(Account.Id accountId, String email) throws Exception {
    accountsUpdate
        .get()
        .update(
            "Test update",
            accountId,
            (a, u) ->
                u.addExternalId(
                    ExternalId.create(
                        "foo",
                        "bar" + accountId.get(),
                        accountId,
                        email,
                        /* hashedPassword= */ null)));
  }
}
