// Copyright (C) 2019 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.base.Preconditions.checkArgument;
import static com.google.gerrit.entities.AccessSection.GLOBAL_CAPABILITIES;
import static java.util.Objects.requireNonNull;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.acceptance.testsuite.ThrowingConsumer;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.PermissionRange;
import com.google.gerrit.entities.PermissionRule;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.config.AllProjectsName;
import java.util.Optional;
import org.eclipse.jgit.lib.Constants;

@AutoValue
public abstract class TestProjectUpdate {
  /** Starts a builder for allowing a capability. */
  public static TestCapability.Builder allowCapability(String name) {
    return TestCapability.builder().name(name);
  }

  /** Records a global capability to be updated. */
  @AutoValue
  public abstract static class TestCapability {
    private static Builder builder() {
      return new AutoValue_TestProjectUpdate_TestCapability.Builder();
    }

    abstract String name();

    abstract AccountGroup.UUID group();

    abstract int min();

    abstract int max();

    /** Builder for {@link TestCapability}. */
    @AutoValue.Builder
    public abstract static class Builder {
      /** Sets the name of the capability. */
      public abstract Builder name(String name);

      abstract String name();

      /** Sets the group to which the capability applies. */
      public abstract Builder group(AccountGroup.UUID group);

      abstract Builder min(int min);

      abstract Optional<Integer> min();

      abstract Builder max(int max);

      abstract Optional<Integer> max();

      /** Sets the minimum and maximum values for the capability. */
      @CanIgnoreReturnValue
      public Builder range(int min, int max) {
        checkNonInvertedRange(min, max);
        return min(min).max(max);
      }

      /** Builds the {@link TestCapability}. */
      abstract TestCapability autoBuild();

      public TestCapability build() {
        PermissionRange.WithDefaults withDefaults = GlobalCapability.getRange(name());
        if (withDefaults != null) {
          int min = min().orElse(withDefaults.getDefaultMin());
          int max = max().orElse(withDefaults.getDefaultMax());
          range(min, max);
          // Don't enforce range is nonempty; this is allowed for e.g. batchChangesLimit.
        } else {
          checkArgument(
              !min().isPresent() && !max().isPresent(),
              "capability %s does not support ranges",
              name());
          range(0, 0);
        }

        return autoBuild();
      }
    }
  }

  /** Starts a builder for allowing a permission. */
  public static TestPermission.Builder allow(String name) {
    return TestPermission.builder().name(name).action(PermissionRule.Action.ALLOW);
  }

  /** Starts a builder for denying a permission. */
  public static TestPermission.Builder deny(String name) {
    return TestPermission.builder().name(name).action(PermissionRule.Action.DENY);
  }

  /** Starts a builder for blocking a permission. */
  public static TestPermission.Builder block(String name) {
    return TestPermission.builder().name(name).action(PermissionRule.Action.BLOCK);
  }

  /**
   * Records a permission to be updated.
   *
   * <p>Not used for permissions that have ranges (label permissions) or global capabilities.
   */
  @AutoValue
  public abstract static class TestPermission {
    private static Builder builder() {
      return new AutoValue_TestProjectUpdate_TestPermission.Builder().force(false);
    }

    abstract String name();

    abstract String ref();

    abstract AccountGroup.UUID group();

    abstract PermissionRule.Action action();

    abstract boolean force();

    /** Builder for {@link TestPermission}. */
    @AutoValue.Builder
    public abstract static class Builder {
      abstract Builder name(String name);

      /** Sets the ref pattern used on the permission. */
      public abstract Builder ref(String ref);

      /** Sets the group to which the permission applies. */
      public abstract Builder group(AccountGroup.UUID groupUuid);

      abstract Builder action(PermissionRule.Action action);

      /** Sets whether the permission is a force permission. */
      public abstract Builder force(boolean force);

      /** Builds the {@link TestPermission}. */
      public abstract TestPermission build();
    }
  }

  /** Starts a builder for allowing a label permission. */
  public static TestLabelPermission.Builder allowLabel(String name) {
    return TestLabelPermission.builder()
        .name(name)
        .isAddPermission(true)
        .action(PermissionRule.Action.ALLOW);
  }

  /** Starts a builder for denying a label permission. */
  public static TestLabelPermission.Builder blockLabel(String name) {
    return TestLabelPermission.builder()
        .name(name)
        .isAddPermission(true)
        .action(PermissionRule.Action.BLOCK);
  }

  /** Starts a builder for allowing a remove-label permission. */
  public static TestLabelPermission.Builder allowLabelRemoval(String name) {
    return TestLabelPermission.builder()
        .name(name)
        .isAddPermission(false)
        .action(PermissionRule.Action.ALLOW);
  }

  /** Starts a builder for denying a remove-label permission. */
  public static TestLabelPermission.Builder blockLabelRemoval(String name) {
    return TestLabelPermission.builder()
        .name(name)
        .isAddPermission(false)
        .action(PermissionRule.Action.BLOCK);
  }

  /** Records a label permission to be updated. */
  @AutoValue
  public abstract static class TestLabelPermission {
    private static Builder builder() {
      return new AutoValue_TestProjectUpdate_TestLabelPermission.Builder().impersonation(false);
    }

    abstract String name();

    abstract String ref();

    abstract AccountGroup.UUID group();

    abstract PermissionRule.Action action();

    abstract int min();

    abstract int max();

    abstract boolean impersonation();

    abstract boolean isAddPermission();

    /** Builder for {@link TestLabelPermission}. */
    @AutoValue.Builder
    public abstract static class Builder {
      abstract Builder name(String name);

      /** Sets the ref pattern used on the permission. */
      public abstract Builder ref(String ref);

      /** Sets the group to which the permission applies. */
      public abstract Builder group(AccountGroup.UUID group);

      abstract Builder action(PermissionRule.Action action);

      abstract Builder min(int min);

      abstract Builder max(int max);

      abstract Builder isAddPermission(boolean isAddPermission);

      /** Sets the minimum and maximum values for the permission. */
      public Builder range(int min, int max) {
        checkArgument(min != 0 || max != 0, "empty range");
        checkNonInvertedRange(min, max);
        return min(min).max(max);
      }

      /** Sets whether this permission should be for impersonating another user's votes. */
      public abstract Builder impersonation(boolean impersonation);

      abstract TestLabelPermission autoBuild();

      /** Builds the {@link TestPermission}. */
      public TestLabelPermission build() {
        TestLabelPermission result = autoBuild();
        checkLabelName(result.name());
        return result;
      }
    }
  }

  /**
   * Starts a builder for describing a permission key for deletion. Not for label permissions or
   * global capabilities.
   */
  public static TestPermissionKey.Builder permissionKey(String name) {
    return TestPermissionKey.builder().name(name);
  }

  /** Starts a builder for describing a label permission key for deletion. */
  public static TestPermissionKey.Builder labelPermissionKey(String name) {
    checkLabelName(name);
    return TestPermissionKey.builder().name(Permission.forLabel(name));
  }

  /** Starts a builder for describing a label removal permission key for deletion. */
  public static TestPermissionKey.Builder labelRemovalPermissionKey(String name) {
    checkLabelName(name);
    return TestPermissionKey.builder().name(Permission.forRemoveLabel(name));
  }

  /** Starts a builder for describing a capability key for deletion. */
  public static TestPermissionKey.Builder capabilityKey(String name) {
    return TestPermissionKey.builder().name(name).section(GLOBAL_CAPABILITIES);
  }

  /** Records the key of a permission (of any type) for deletion. */
  @AutoValue
  public abstract static class TestPermissionKey {
    private static Builder builder() {
      return new AutoValue_TestProjectUpdate_TestPermissionKey.Builder();
    }

    abstract String section();

    abstract String name();

    abstract Optional<AccountGroup.UUID> group();

    @AutoValue.Builder
    public abstract static class Builder {
      abstract Builder section(String section);

      abstract Optional<String> section();

      /** Sets the ref pattern used on the permission. Not for global capabilities. */
      public Builder ref(String ref) {
        requireNonNull(ref);
        checkArgument(ref.startsWith(Constants.R_REFS), "must be a ref: %s", ref);
        checkArgument(
            !section().isPresent() || !section().get().equals(GLOBAL_CAPABILITIES),
            "can't set ref on global capability");
        return section(ref);
      }

      abstract Builder name(String name);

      /** Sets the group to which the permission applies. */
      public abstract Builder group(AccountGroup.UUID group);

      /** Builds the {@link TestPermissionKey}. */
      public abstract TestPermissionKey build();
    }
  }

  static Builder builder(
      Project.NameKey nameKey,
      AllProjectsName allProjectsName,
      ThrowingConsumer<TestProjectUpdate> projectUpdater) {
    return new AutoValue_TestProjectUpdate.Builder()
        .nameKey(nameKey)
        .allProjectsName(allProjectsName)
        .projectUpdater(projectUpdater)
        .removeAllAccessSections(false);
  }

  /** Builder for {@link TestProjectUpdate}. */
  @AutoValue.Builder
  public abstract static class Builder {
    abstract Builder nameKey(Project.NameKey project);

    abstract Builder allProjectsName(AllProjectsName allProjects);

    abstract ImmutableList.Builder<TestPermission> addedPermissionsBuilder();

    abstract ImmutableList.Builder<TestLabelPermission> addedLabelPermissionsBuilder();

    abstract ImmutableList.Builder<TestCapability> addedCapabilitiesBuilder();

    abstract ImmutableList.Builder<TestPermissionKey> removedPermissionsBuilder();

    abstract ImmutableMap.Builder<TestPermissionKey, Boolean> exclusiveGroupPermissionsBuilder();

    abstract Builder removeAllAccessSections(boolean value);

    /**
     * Removes all access sections. Useful when testing against a specific set of access sections or
     * permissions.
     */
    @CanIgnoreReturnValue
    public Builder removeAllAccessSections() {
      return removeAllAccessSections(true);
    }

    /** Adds a permission to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestPermission testPermission) {
      addedPermissionsBuilder().add(testPermission);
      return this;
    }

    /** Adds a permission to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestPermission.Builder testPermissionBuilder) {
      return add(testPermissionBuilder.build());
    }

    /** Adds a label permission to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestLabelPermission testLabelPermission) {
      addedLabelPermissionsBuilder().add(testLabelPermission);
      return this;
    }

    /** Adds a label permission to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestLabelPermission.Builder testLabelPermissionBuilder) {
      return add(testLabelPermissionBuilder.build());
    }

    /** Adds a capability to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestCapability testCapability) {
      addedCapabilitiesBuilder().add(testCapability);
      return this;
    }

    /** Adds a capability to be included in this update. */
    @CanIgnoreReturnValue
    public Builder add(TestCapability.Builder testCapabilityBuilder) {
      return add(testCapabilityBuilder.build());
    }

    /** Removes a permission, label permission, or capability as part of this update. */
    @CanIgnoreReturnValue
    public Builder remove(TestPermissionKey testPermissionKey) {
      removedPermissionsBuilder().add(testPermissionKey);
      return this;
    }

    /** Removes a permission, label permission, or capability as part of this update. */
    @CanIgnoreReturnValue
    public Builder remove(TestPermissionKey.Builder testPermissionKeyBuilder) {
      return remove(testPermissionKeyBuilder.build());
    }

    /** Sets the exclusive bit bit for the given permission key. */
    @CanIgnoreReturnValue
    public Builder setExclusiveGroup(
        TestPermissionKey.Builder testPermissionKeyBuilder, boolean exclusive) {
      return setExclusiveGroup(testPermissionKeyBuilder.build(), exclusive);
    }

    /** Sets the exclusive bit bit for the given permission key. */
    @CanIgnoreReturnValue
    public Builder setExclusiveGroup(TestPermissionKey testPermissionKey, boolean exclusive) {
      checkArgument(
          !testPermissionKey.group().isPresent(),
          "do not specify group for setExclusiveGroup: %s",
          testPermissionKey);
      checkArgument(
          !testPermissionKey.section().equals(GLOBAL_CAPABILITIES),
          "setExclusiveGroup not valid for global capabilities: %s",
          testPermissionKey);
      exclusiveGroupPermissionsBuilder().put(testPermissionKey, exclusive);
      return this;
    }

    abstract Builder projectUpdater(ThrowingConsumer<TestProjectUpdate> projectUpdater);

    abstract TestProjectUpdate autoBuild();

    TestProjectUpdate build() {
      TestProjectUpdate projectUpdate = autoBuild();
      if (projectUpdate.hasCapabilityUpdates()) {
        checkArgument(
            projectUpdate.nameKey().equals(projectUpdate.allProjectsName()),
            "cannot update global capabilities on %s, only %s: %s",
            projectUpdate.nameKey(),
            projectUpdate.allProjectsName(),
            projectUpdate);
      }
      return projectUpdate;
    }

    /** Executes the update, updating the underlying project. */
    public void update() {
      TestProjectUpdate projectUpdate = build();
      projectUpdate.projectUpdater().acceptAndThrowSilently(projectUpdate);
    }
  }

  abstract Project.NameKey nameKey();

  abstract AllProjectsName allProjectsName();

  abstract ImmutableList<TestPermission> addedPermissions();

  abstract ImmutableList<TestLabelPermission> addedLabelPermissions();

  abstract ImmutableList<TestCapability> addedCapabilities();

  abstract ImmutableList<TestPermissionKey> removedPermissions();

  abstract ImmutableMap<TestPermissionKey, Boolean> exclusiveGroupPermissions();

  abstract ThrowingConsumer<TestProjectUpdate> projectUpdater();

  abstract boolean removeAllAccessSections();

  boolean hasCapabilityUpdates() {
    return !addedCapabilities().isEmpty()
        || removedPermissions().stream().anyMatch(k -> k.section().equals(GLOBAL_CAPABILITIES));
  }

  private static void checkLabelName(String name) {
    // "label-Code-Review" is technically a valid label name, and we don't prevent users from
    // using it in production, but specifying it in a test is programmer error.
    checkArgument(!Permission.isLabel(name), "expected label name, got permission name: %s", name);
    LabelType.checkName(name);
  }

  private static void checkNonInvertedRange(int min, int max) {
    checkArgument(min <= max, "inverted range: %s > %s", min, max);
  }
}
