// 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.common.data.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.gerrit.acceptance.testsuite.ThrowingConsumer;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.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. */
      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).action(PermissionRule.Action.ALLOW);
  }

  /** Starts a builder for denying a label permission. */
  public static TestLabelPermission.Builder blockLabel(String name) {
    return TestLabelPermission.builder().name(name).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();

    /** 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);

      /** 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 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);
  }

  /** 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();

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

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

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

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

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

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

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

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

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

    /** Sets the exclusive bit bit for the given permission key. */
    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();

  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);
  }
}
