// Copyright (C) 2017 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.server.group.db;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import java.sql.Timestamp;
import java.util.Optional;
import java.util.Set;

/**
 * Data holder for updates to be applied to a group.
 *
 * <p>A {@link GroupDelta} specifies the modifications to be applied to a group. Only fields set via
 * {@link GroupDelta.Builder} will be updated.
 */
@AutoValue
public abstract class GroupDelta {

  /** Representation of a member modification as defined by {@link #apply(ImmutableSet)}. */
  @FunctionalInterface
  public interface MemberModification {

    /**
     * Applies the modification to the given members.
     *
     * @param originalMembers current members of the group. If used for a group creation, this set
     *     is empty.
     * @return the desired resulting members (not the diff of the members!)
     */
    Set<Account.Id> apply(ImmutableSet<Account.Id> originalMembers);
  }

  @FunctionalInterface
  public interface SubgroupModification {
    /**
     * Applies the modification to the given subgroups.
     *
     * @param originalSubgroups current subgroups of the group. If used for a group creation, this
     *     set is empty.
     * @return the desired resulting subgroups (not the diff of the subgroups!)
     */
    Set<AccountGroup.UUID> apply(ImmutableSet<AccountGroup.UUID> originalSubgroups);
  }

  /** Defines the new name of the group. If not specified, the name remains unchanged. */
  public abstract Optional<AccountGroup.NameKey> getName();

  /**
   * Defines the new description of the group. If not specified, the description remains unchanged.
   *
   * <p><strong>Note: </strong>Passing the empty string unsets the description.
   */
  public abstract Optional<String> getDescription();

  /** Defines the new owner of the group. If not specified, the owner remains unchanged. */
  public abstract Optional<AccountGroup.UUID> getOwnerGroupUUID();

  /**
   * Defines the new state of the 'visibleToAll' flag of the group. If not specified, the flag
   * remains unchanged.
   */
  public abstract Optional<Boolean> getVisibleToAll();

  /**
   * Defines how the members of the group should be modified. By default (that is if nothing is
   * specified), the members remain unchanged.
   *
   * @return a {@link MemberModification} which gets the current members of the group as input and
   *     outputs the desired resulting members
   */
  public abstract MemberModification getMemberModification();

  /**
   * Defines how the subgroups of the group should be modified. By default (that is if nothing is
   * specified), the subgroups remain unchanged.
   *
   * @return a {@link SubgroupModification} which gets the current subgroups of the group as input
   *     and outputs the desired resulting subgroups
   */
  public abstract SubgroupModification getSubgroupModification();

  /**
   * Defines the {@code Timestamp} to be used for the NoteDb commits of the update. If not
   * specified, the current {@code Timestamp} when creating the commit will be used.
   *
   * <p>If this {@link GroupDelta} is passed next to an {@link InternalGroupCreation} during a group
   * creation, this {@code Timestamp} is used for the NoteDb commits of the new group. Hence, the
   * {@link com.google.gerrit.entities.InternalGroup#getCreatedOn() InternalGroup#getCreatedOn()}
   * field will match this {@code Timestamp}.
   *
   * <p><strong>Note: </strong>{@code Timestamp}s of NoteDb commits for groups are used for events
   * in the audit log. For this reason, specifying this field will have an effect on the resulting
   * audit log.
   */
  public abstract Optional<Timestamp> getUpdatedOn();

  public abstract Builder toBuilder();

  public static Builder builder() {
    return new AutoValue_GroupDelta.Builder()
        .setMemberModification(in -> in)
        .setSubgroupModification(in -> in);
  }

  /** A builder for a {@link GroupDelta}. */
  @AutoValue.Builder
  public abstract static class Builder {

    /**
     * Defines the new name of the group
     *
     * <p>See {@link #getName}.
     */
    public abstract Builder setName(AccountGroup.NameKey name);

    /**
     * Defines the new description of the group
     *
     * <p>See {@link #getDescription()}}
     */
    public abstract Builder setDescription(String description);

    /**
     * Defines the new owner of the group
     *
     * <p>See {@link #getOwnerGroupUUID()}
     */
    public abstract Builder setOwnerGroupUUID(AccountGroup.UUID ownerGroupUUID);

    /**
     * Defines the new state of the 'visibleToAll' flag of the group
     *
     * <p>See {@link #getVisibleToAll()}
     */
    public abstract Builder setVisibleToAll(boolean visibleToAll);

    /**
     * Set {@link MemberModification} for the prospective {@link GroupDelta}
     *
     * <p>See {@link #getMemberModification()}
     */
    public abstract Builder setMemberModification(MemberModification memberModification);

    /**
     * Returns the currently defined {@link MemberModification} for the prospective {@link
     * GroupDelta}.
     *
     * <p>This modification can be tweaked further and passed to {@link
     * #setMemberModification(GroupDelta.MemberModification)} in order to combine multiple member
     * additions, deletions, or other modifications into one update.
     */
    public abstract MemberModification getMemberModification();

    /**
     * Set {@link SubgroupModification} for the prospective {@link GroupDelta}
     *
     * <p>See {@link #getSubgroupModification()}
     */
    public abstract Builder setSubgroupModification(SubgroupModification subgroupModification);

    /**
     * Returns the currently defined {@link SubgroupModification} for the prospective {@link
     * GroupDelta}.
     *
     * <p>This modification can be tweaked further and passed to {@link
     * #setSubgroupModification(GroupDelta.SubgroupModification)} in order to combine multiple
     * subgroup additions, deletions, or other modifications into one update.
     */
    public abstract SubgroupModification getSubgroupModification();

    /**
     * Defines the {@code Timestamp} to be used for the NoteDb commits of the update. If not
     * specified, the current {@code Timestamp} when creating the commit will be used.
     *
     * <p>See {@link #getUpdatedOn()}
     */
    public abstract Builder setUpdatedOn(Timestamp timestamp);

    public abstract GroupDelta build();
  }
}
