// Copyright (C) 2018 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.testsuite.project;

import static com.google.common.truth.Truth.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.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabelRemoval;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabelRemoval;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelRemovalPermissionKey;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
import static com.google.gerrit.common.data.GlobalCapability.QUERY_LIMIT;
import static com.google.gerrit.entities.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.group.SystemGroupBackend.PROJECT_OWNERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.truth.Correspondence;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestPermission;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.truth.NullAwareCorrespondence;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.junit.Test;

public class ProjectOperationsImplTest extends AbstractDaemonTest {

  @Inject private ProjectOperations projectOperations;
  @Inject private GroupOperations groupsOperations;

  @Test
  public void defaultName() throws Exception {
    Project.NameKey name = projectOperations.newProject().create();

    // check that the project was created (throws exception if not found.)
    @SuppressWarnings("unused")
    var unused = gApi.projects().name(name.get());

    Project.NameKey name2 = projectOperations.newProject().create();
    assertThat(name2).isNotEqualTo(name);
  }

  @Test
  public void specifiedName() throws Exception {
    String name = "somename";
    Project.NameKey key = projectOperations.newProject().name(name).create();
    assertThat(key.get()).isEqualTo(name);
  }

  @Test
  public void emptyCommit() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();

    List<BranchInfo> branches = gApi.projects().name(key.get()).branches().get();
    assertThat(branches).isNotEmpty();
    assertThat(branches.stream().map(x -> x.ref).collect(toList()))
        .isEqualTo(ImmutableList.of("HEAD", "refs/meta/config", "refs/heads/master"));
  }

  @Test
  public void specifiedBranchesAreCreatedInNewProject() throws Exception {
    Project.NameKey project =
        projectOperations
            .newProject()
            .branches("test-branch", "refs/heads/another-test-branch")
            .create();

    List<BranchInfo> branches = gApi.projects().name(project.get()).branches().get();
    assertThat(branches)
        .comparingElementsUsing(hasBranchName())
        .containsAtLeast("refs/heads/test-branch", "refs/heads/another-test-branch");
  }

  @Test
  public void specifiedBranchesAreNotCreatedInNewProjectIfNoEmptyCommitRequested()
      throws Exception {
    Project.NameKey project =
        projectOperations
            .newProject()
            .branches("test-branch", "refs/heads/another-test-branch")
            .noEmptyCommit()
            .create();

    List<BranchInfo> branches = gApi.projects().name(project.get()).branches().get();
    assertThat(branches)
        .comparingElementsUsing(hasBranchName())
        .containsNoneOf("refs/heads/test-branch", "refs/heads/another-test-branch");
  }

  @Test
  public void permissionOnly() throws Exception {
    Project.NameKey key = projectOperations.newProject().permissionOnly(true).create();
    String head = gApi.projects().name(key.get()).head();
    assertThat(head).isEqualTo(RefNames.REFS_CONFIG);
  }

  @Test
  public void createWithOwners() throws Exception {
    AccountGroup.UUID uuid = groupsOperations.newGroup().create();
    Project.NameKey key = projectOperations.newProject().addOwner(uuid).create();
    assertPermissions(key, groupRef(uuid), "refs/*", false, Permission.OWNER);
  }

  @Test
  public void getProjectConfig() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    assertThat(projectOperations.project(key).getProjectConfig().getProject().getDescription())
        .isEmpty();

    ConfigInput input = new ConfigInput();
    input.description = "my fancy project";
    gApi.projects().name(key.get()).config(input);

    assertThat(projectOperations.project(key).getProjectConfig().getProject().getDescription())
        .isEqualTo("my fancy project");
  }

  @Test
  public void getProjectConfigNoRefsMetaConfig() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    deleteRefsMetaConfig(key);

    ProjectConfig projectConfig = projectOperations.project(key).getProjectConfig();
    assertThat(projectConfig.getName()).isEqualTo(key);
    assertThat(projectConfig.getRevision()).isNull();
  }

  @Test
  public void getConfig() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    Config config = projectOperations.project(key).getConfig();
    assertThat(config).isNotInstanceOf(StoredConfig.class);
    assertThat(config).sections().containsExactly("submit");
    assertThat(config).sectionValues("submit").containsExactly("action", "inherit");

    ConfigInput input = new ConfigInput();
    input.description = "my fancy project";
    gApi.projects().name(key.get()).config(input);

    config = projectOperations.project(key).getConfig();
    assertThat(config).isNotInstanceOf(StoredConfig.class);
    assertThat(config).sections().containsExactly("project", "submit");
    assertThat(config).subsections("project").isEmpty();
    assertThat(config).sectionValues("project").containsExactly("description", "my fancy project");
  }

  @Test
  public void getConfigNoRefsMetaConfig() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    deleteRefsMetaConfig(key);

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).isNotInstanceOf(StoredConfig.class);
    assertThat(config).isEmpty();
  }

  @Test
  public void addAllowPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "group global:Registered-Users");
  }

  @Test
  public void addDenyPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(deny(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "deny group global:Registered-Users");
  }

  @Test
  public void addBlockPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(block(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "block group global:Registered-Users");
  }

  @Test
  public void addAllowForcePermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS).force(true))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "+force group global:Registered-Users");
  }

  @Test
  public void updateExclusivePermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), true)
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "abandon", "group global:Registered-Users",
            "exclusiveGroupPermissions", "abandon");

    projectOperations
        .project(key)
        .forUpdate()
        .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), false)
        .update();

    config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "group global:Registered-Users");
  }

  @Test
  public void addMultipleExclusivePermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), true)
        .setExclusiveGroup(permissionKey(Permission.CREATE).ref("refs/foo"), true)
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsEntry("exclusiveGroupPermissions", "abandon create");

    projectOperations
        .project(key)
        .forUpdate()
        .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), false)
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsEntry("exclusiveGroupPermissions", "create");
  }

  @Test
  public void addMultiplePermissions() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
        .add(allow(Permission.CREATE).ref("refs/foo").group(REGISTERED_USERS))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "abandon", "group global:Project-Owners",
            "create", "group global:Registered-Users");
  }

  @Test
  public void addDuplicatePermissions_isIgnored() throws Exception {
    TestPermission permission =
        TestProjectUpdate.allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS).build();
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations.project(key).forUpdate().add(permission).add(permission).update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().contains("access");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        // Duplicated permission was recorded only once
        .containsExactly("abandon", "group global:Registered-Users");

    projectOperations.project(key).forUpdate().add(permission).update();
    config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        // Duplicated permission in request was dropped
        .containsExactly("abandon", "group global:Registered-Users");
  }

  @Test
  public void addAllowLabelPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("label-Code-Review", "-1..+2 group global:Registered-Users");
  }

  @Test
  public void addBlockLabelPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(blockLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("label-Code-Review", "block -1..+2 group global:Registered-Users");
  }

  @Test
  public void addAllowExclusiveLabelPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/foo"), true)
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "label-Code-Review", "-1..+2 group global:Registered-Users",
            "exclusiveGroupPermissions", "label-Code-Review");

    projectOperations
        .project(key)
        .forUpdate()
        .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/foo"), false)
        .update();

    config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("label-Code-Review", "-1..+2 group global:Registered-Users");
  }

  @Test
  public void addAllowLabelAsPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(
            allowLabel("Code-Review")
                .ref("refs/foo")
                .group(REGISTERED_USERS)
                .range(-1, 2)
                .impersonation(true))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("labelAs-Code-Review", "-1..+2 group global:Registered-Users");
  }

  @Test
  public void addAllowLabelRemovalPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabelRemoval("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("removeLabel-Code-Review", "-1..+2 group global:Registered-Users");
  }

  @Test
  public void addBlockLabelRemovalPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(blockLabelRemoval("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("removeLabel-Code-Review", "block -1..+2 group global:Registered-Users");
  }

  @Test
  public void addAllowExclusiveLabelRemovalPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabelRemoval("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .setExclusiveGroup(labelRemovalPermissionKey("Code-Review").ref("refs/foo"), true)
        .update();

    Config config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "removeLabel-Code-Review", "-1..+2 group global:Registered-Users",
            "exclusiveGroupPermissions", "removeLabel-Code-Review");

    projectOperations
        .project(key)
        .forUpdate()
        .setExclusiveGroup(labelRemovalPermissionKey("Code-Review").ref("refs/foo"), false)
        .update();

    config = projectOperations.project(key).getConfig();
    assertThat(config).sections().containsExactly("access", "submit");
    assertThat(config).subsections("access").containsExactly("refs/foo");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsExactly("removeLabel-Code-Review", "-1..+2 group global:Registered-Users");
  }

  @Test
  public void addAllowCapability() throws Exception {
    Config config = projectOperations.project(allProjects).getConfig();
    assertThat(config)
        .sectionValues("capability")
        .doesNotContainEntry("administrateServer", "group Registered Users");

    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
        .update();

    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("capability")
        .containsEntry("administrateServer", "group Registered Users");
  }

  @Test
  public void addAllowCapabilityWithRange() throws Exception {
    Config config = projectOperations.project(allProjects).getConfig();
    assertThat(config).sectionValues("capability").doesNotContainKey("queryLimit");

    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).range(0, 5000))
        .update();

    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("capability")
        .containsEntry("queryLimit", "+0..+5000 group Registered Users");
  }

  @Test
  public void addAllowCapabilityWithDefaultRange() throws Exception {
    Config config = projectOperations.project(allProjects).getConfig();
    assertThat(config).sectionValues("capability").doesNotContainKey("queryLimit");

    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(QUERY_LIMIT).group(REGISTERED_USERS))
        .update();

    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("capability")
        .containsEntry("queryLimit", "+0..+" + DEFAULT_MAX_QUERY_LIMIT + " group Registered Users");
  }

  @Test
  public void removePermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "abandon", "group global:Registered-Users",
            "abandon", "group global:Project-Owners");

    projectOperations
        .project(key)
        .forUpdate()
        .remove(permissionKey(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly("abandon", "group global:Project-Owners");
  }

  @Test
  public void removeLabelPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .add(allowLabel("Code-Review").ref("refs/foo").group(PROJECT_OWNERS).range(-2, 1))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "label-Code-Review", "-1..+2 group global:Registered-Users",
            "label-Code-Review", "-2..+1 group global:Project-Owners");

    projectOperations
        .project(key)
        .forUpdate()
        .remove(labelPermissionKey("Code-Review").ref("refs/foo").group(REGISTERED_USERS))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly("label-Code-Review", "-2..+1 group global:Project-Owners");
  }

  @Test
  public void removeLabelRemovalPermission() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allowLabelRemoval("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
        .add(allowLabelRemoval("Code-Review").ref("refs/foo").group(PROJECT_OWNERS).range(-2, 1))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly(
            "removeLabel-Code-Review", "-1..+2 group global:Registered-Users",
            "removeLabel-Code-Review", "-2..+1 group global:Project-Owners");

    projectOperations
        .project(key)
        .forUpdate()
        .remove(labelRemovalPermissionKey("Code-Review").ref("refs/foo").group(REGISTERED_USERS))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsExactly("removeLabel-Code-Review", "-2..+1 group global:Project-Owners");
  }

  @Test
  public void removeCapability() throws Exception {
    projectOperations
        .allProjectsForUpdate()
        .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
        .add(allowCapability(ADMINISTRATE_SERVER).group(PROJECT_OWNERS))
        .update();
    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("capability")
        .containsAtLeastEntriesIn(
            ImmutableListMultimap.of(
                "administrateServer", "group Registered Users",
                "administrateServer", "group Project Owners"));

    projectOperations
        .allProjectsForUpdate()
        .remove(capabilityKey(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
        .update();
    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("capability")
        .doesNotContainEntry("administrateServer", "group Registered Users");
  }

  @Test
  public void removeOnePermissionForAllGroupsFromOneAccessSection() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    projectOperations
        .project(key)
        .forUpdate()
        .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
        .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
        .add(allow(Permission.CREATE).ref("refs/foo").group(REGISTERED_USERS))
        .update();
    assertThat(projectOperations.project(key).getConfig())
        .subsectionValues("access", "refs/foo")
        .containsAtLeastEntriesIn(
            ImmutableListMultimap.of(
                "abandon", "group global:Project-Owners",
                "abandon", "group global:Registered-Users",
                "create", "group global:Registered-Users"));

    projectOperations
        .project(key)
        .forUpdate()
        .remove(permissionKey(Permission.ABANDON).ref("refs/foo"))
        .update();
    Config config = projectOperations.project(key).getConfig();
    assertThat(config).subsectionValues("access", "refs/foo").doesNotContainKey("abandon");
    assertThat(config)
        .subsectionValues("access", "refs/foo")
        .containsEntry("create", "group global:Registered-Users");
  }

  @Test
  public void removeAllAccessSections() {
    projectOperations.allProjectsForUpdate().removeAllAccessSections().update();

    assertThat(projectOperations.project(allProjects).getConfig())
        .sectionValues("access")
        .isEmpty();
  }

  @Test
  public void updatingCapabilitiesNotAllowedForNonAllProjects() throws Exception {
    Project.NameKey key = projectOperations.newProject().create();
    assertThrows(
        RuntimeException.class,
        () ->
            projectOperations
                .project(key)
                .forUpdate()
                .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
                .update());
    assertThrows(
        RuntimeException.class,
        () ->
            projectOperations
                .project(key)
                .forUpdate()
                .remove(capabilityKey(ADMINISTRATE_SERVER))
                .update());
  }

  private void deleteRefsMetaConfig(Project.NameKey key) throws Exception {
    try (Repository repo = repoManager.openRepository(key);
        TestRepository<Repository> tr = new TestRepository<>(repo)) {
      tr.delete(REFS_CONFIG);
    }
  }

  private static Correspondence<BranchInfo, String> hasBranchName() {
    return NullAwareCorrespondence.transforming(branch -> branch.ref, "hasName");
  }
}
