// 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 Licens

package com.google.gerrit.server.account;

import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.NotifyConfig.NotifyType;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.EditPreferencesInfo;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.server.account.ProjectWatches.ProjectWatchKey;
import com.google.gerrit.server.account.externalids.DuplicateExternalIdKeyException;
import com.google.gerrit.server.account.externalids.ExternalId;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Data holder for updates to be applied to an account.
 *
 * <p>Instances of this type are passed to {@link AccountsUpdate}, which modifies the account
 * accordingly.
 *
 * <p>Updates can be applied to account properties (name, email etc.), external IDs, preferences
 * (general, diff and edit preferences) and project watches. The account ID and the registration
 * date cannot be updated.
 *
 * <p>For the account properties there are getters in this class and setters in the {@link Builder}
 * that correspond to the fields in {@link Account}.
 */
@AutoValue
public abstract class AccountDelta {
  public static Builder builder() {
    return new Builder.WrapperThatConvertsNullStringArgsToEmptyStrings(
        new AutoValue_AccountDelta.Builder());
  }

  /**
   * Returns the new value for the full name.
   *
   * @return the new value for the full name, {@code Optional#empty()} if the full name is not being
   *     updated, {@code Optional#of("")} if the full name is unset, the wrapped value is never
   *     {@code null}
   */
  public abstract Optional<String> getFullName();

  /**
   * Returns the new value for the display name.
   *
   * @return the new value for the display name, {@code Optional#empty()} if the display name is not
   *     being updated, {@code Optional#of("")} if the display name is unset, the wrapped value is
   *     never {@code null}
   */
  public abstract Optional<String> getDisplayName();

  /**
   * Returns the new value for the preferred email.
   *
   * @return the new value for the preferred email, {@code Optional#empty()} if the preferred email
   *     is not being updated, {@code Optional#of("")} if the preferred email is unset, the wrapped
   *     value is never {@code null}
   */
  public abstract Optional<String> getPreferredEmail();

  /**
   * Returns the new value for the active flag.
   *
   * @return the new value for the active flag, {@code Optional#empty()} if the active flag is not
   *     being updated, the wrapped value is never {@code null}
   */
  public abstract Optional<Boolean> getActive();

  /**
   * Returns the new value for the status.
   *
   * @return the new value for the status, {@code Optional#empty()} if the status is not being
   *     updated, {@code Optional#of("")} if the status is unset, the wrapped value is never {@code
   *     null}
   */
  public abstract Optional<String> getStatus();

  /**
   * Returns external IDs that should be newly created for the account.
   *
   * @return external IDs that should be newly created for the account
   */
  public abstract ImmutableSet<ExternalId> getCreatedExternalIds();

  /**
   * Returns external IDs that should be updated for the account.
   *
   * @return external IDs that should be updated for the account
   */
  public abstract ImmutableSet<ExternalId> getUpdatedExternalIds();

  /**
   * Returns external IDs that should be deleted for the account.
   *
   * @return external IDs that should be deleted for the account
   */
  public abstract ImmutableSet<ExternalId> getDeletedExternalIds();

  /**
   * Returns external IDs that should be updated for the account.
   *
   * @return external IDs that should be updated for the account
   */
  public abstract ImmutableMap<ProjectWatchKey, Set<NotifyType>> getUpdatedProjectWatches();

  /**
   * Returns project watches that should be deleted for the account.
   *
   * @return project watches that should be deleted for the account
   */
  public abstract ImmutableSet<ProjectWatchKey> getDeletedProjectWatches();

  /**
   * Returns the new value for the general preferences.
   *
   * <p>Only preferences that are non-null in the returned GeneralPreferencesInfo should be updated.
   *
   * @return the new value for the general preferences, {@code Optional#empty()} if the general
   *     preferences are not being updated, the wrapped value is never {@code null}
   */
  public abstract Optional<GeneralPreferencesInfo> getGeneralPreferences();

  /**
   * Returns the new value for the diff preferences.
   *
   * <p>Only preferences that are non-null in the returned DiffPreferencesInfo should be updated.
   *
   * @return the new value for the diff preferences, {@code Optional#empty()} if the diff
   *     preferences are not being updated, the wrapped value is never {@code null}
   */
  public abstract Optional<DiffPreferencesInfo> getDiffPreferences();

  /**
   * Returns the new value for the edit preferences.
   *
   * <p>Only preferences that are non-null in the returned DiffPreferencesInfo should be updated.
   *
   * @return the new value for the edit preferences, {@code Optional#empty()} if the edit
   *     preferences are not being updated, the wrapped value is never {@code null}
   */
  public abstract Optional<EditPreferencesInfo> getEditPreferences();

  /**
   * Class to build an {@link AccountDelta}.
   *
   * <p>Account data is only updated if the corresponding setter is invoked. If a setter is not
   * invoked the corresponding data stays unchanged. To unset string values the setter can be
   * invoked with either {@code null} or an empty string ({@code null} is converted to an empty
   * string by using the {@link WrapperThatConvertsNullStringArgsToEmptyStrings} wrapper, see {@link
   * AccountDelta#builder()}).
   */
  @AutoValue.Builder
  public abstract static class Builder {
    /**
     * Sets a new full name for the account.
     *
     * @param fullName the new full name, if {@code null} or empty string the full name is unset
     */
    public abstract Builder setFullName(@Nullable String fullName);

    /**
     * Sets a new display name for the account.
     *
     * @param displayName the new display name, if {@code null} or empty string the display name is
     *     unset
     */
    public abstract Builder setDisplayName(@Nullable String displayName);

    /**
     * Sets a new preferred email for the account.
     *
     * @param preferredEmail the new preferred email, if {@code null} or empty string the preferred
     *     email is unset
     */
    public abstract Builder setPreferredEmail(@Nullable String preferredEmail);

    /**
     * Sets the active flag for the account.
     *
     * @param active {@code true} if the account should be set to active, {@code false} if the
     *     account should be set to inactive
     */
    public abstract Builder setActive(boolean active);

    /**
     * Sets a new status for the account.
     *
     * @param status the new status, if {@code null} or empty string the status is unset
     */
    public abstract Builder setStatus(@Nullable String status);

    /**
     * Returns a builder for the set of created external IDs.
     *
     * @return builder for the set of created external IDs.
     */
    abstract ImmutableSet.Builder<ExternalId> createdExternalIdsBuilder();

    /**
     * Adds a new external ID for the account.
     *
     * <p>The account ID of the external ID must match the account ID of the account that is
     * updated.
     *
     * <p>If an external ID with the same ID already exists the account update will fail with {@link
     * DuplicateExternalIdKeyException}.
     *
     * @param extId external ID that should be added
     * @return the builder
     */
    public Builder addExternalId(ExternalId extId) {
      return addExternalIds(ImmutableSet.of(extId));
    }

    /**
     * Adds new external IDs for the account.
     *
     * <p>The account IDs of the external IDs must match the account ID of the account that is
     * updated.
     *
     * <p>If any of the external ID keys already exists, the insert fails with {@link
     * DuplicateExternalIdKeyException}.
     *
     * @param extIds external IDs that should be added
     * @return the builder
     */
    public Builder addExternalIds(Collection<ExternalId> extIds) {
      createdExternalIdsBuilder().addAll(extIds);
      return this;
    }

    /**
     * Returns a builder for the set of updated external IDs.
     *
     * @return builder for the set of updated external IDs.
     */
    abstract ImmutableSet.Builder<ExternalId> updatedExternalIdsBuilder();

    /**
     * Updates an external ID for the account.
     *
     * <p>The account ID of the external ID must match the account ID of the account that is
     * updated.
     *
     * <p>If no external ID with the ID exists the external ID is created.
     *
     * @param extId external ID that should be updated
     * @return the builder
     */
    public Builder updateExternalId(ExternalId extId) {
      return updateExternalIds(ImmutableSet.of(extId));
    }

    /**
     * Updates external IDs for the account.
     *
     * <p>The account IDs of the external IDs must match the account ID of the account that is
     * updated.
     *
     * <p>If any of the external IDs already exists, it is overwritten. New external IDs are
     * inserted.
     *
     * @param extIds external IDs that should be updated
     * @return the builder
     */
    public Builder updateExternalIds(Collection<ExternalId> extIds) {
      updatedExternalIdsBuilder().addAll(extIds);
      return this;
    }

    /**
     * Returns a builder for the set of deleted external IDs.
     *
     * @return builder for the set of deleted external IDs.
     */
    abstract ImmutableSet.Builder<ExternalId> deletedExternalIdsBuilder();

    /**
     * Deletes an external ID for the account.
     *
     * <p>The account ID of the external ID must match the account ID of the account that is
     * updated.
     *
     * <p>If no external ID with the ID exists this is a no-op.
     *
     * @param extId external ID that should be deleted
     * @return the builder
     */
    public Builder deleteExternalId(ExternalId extId) {
      return deleteExternalIds(ImmutableSet.of(extId));
    }

    /**
     * Deletes external IDs for the account.
     *
     * <p>The account IDs of the external IDs must match the account ID of the account that is
     * updated.
     *
     * <p>For non-existing external IDs this is a no-op.
     *
     * @param extIds external IDs that should be deleted
     * @return the builder
     */
    public Builder deleteExternalIds(Collection<ExternalId> extIds) {
      deletedExternalIdsBuilder().addAll(extIds);
      return this;
    }

    /**
     * Replaces an external ID.
     *
     * @param extIdToDelete external ID that should be deleted
     * @param extIdToAdd external ID that should be added
     * @return the builder
     */
    public Builder replaceExternalId(ExternalId extIdToDelete, ExternalId extIdToAdd) {
      return replaceExternalIds(ImmutableSet.of(extIdToDelete), ImmutableSet.of(extIdToAdd));
    }

    /**
     * Replaces an external IDs.
     *
     * @param extIdsToDelete external IDs that should be deleted
     * @param extIdsToAdd external IDs that should be added
     * @return the builder
     */
    public Builder replaceExternalIds(
        Collection<ExternalId> extIdsToDelete, Collection<ExternalId> extIdsToAdd) {
      return deleteExternalIds(extIdsToDelete).addExternalIds(extIdsToAdd);
    }

    /**
     * Returns a builder for the map of updated project watches.
     *
     * @return builder for the map of updated project watches.
     */
    abstract ImmutableMap.Builder<ProjectWatchKey, Set<NotifyType>> updatedProjectWatchesBuilder();

    /**
     * Updates a project watch for the account.
     *
     * <p>If no project watch with the key exists the project watch is created.
     *
     * @param projectWatchKey key of the project watch that should be updated
     * @param notifyTypes the notify types that should be set for the project watch
     * @return the builder
     */
    public Builder updateProjectWatch(
        ProjectWatchKey projectWatchKey, Set<NotifyType> notifyTypes) {
      return updateProjectWatches(ImmutableMap.of(projectWatchKey, notifyTypes));
    }

    /**
     * Updates project watches for the account.
     *
     * <p>If any of the project watches already exists, it is overwritten. New project watches are
     * inserted.
     *
     * @param projectWatches project watches that should be updated
     * @return the builder
     */
    public Builder updateProjectWatches(Map<ProjectWatchKey, Set<NotifyType>> projectWatches) {
      updatedProjectWatchesBuilder().putAll(projectWatches);
      return this;
    }

    /**
     * Returns a builder for the set of deleted project watches.
     *
     * @return builder for the set of deleted project watches.
     */
    abstract ImmutableSet.Builder<ProjectWatchKey> deletedProjectWatchesBuilder();

    /**
     * Deletes a project watch for the account.
     *
     * <p>If no project watch with the ID exists this is a no-op.
     *
     * @param projectWatch project watch that should be deleted
     * @return the builder
     */
    public Builder deleteProjectWatch(ProjectWatchKey projectWatch) {
      return deleteProjectWatches(ImmutableSet.of(projectWatch));
    }

    /**
     * Deletes project watches for the account.
     *
     * <p>For non-existing project watches this is a no-op.
     *
     * @param projectWatches project watches that should be deleted
     * @return the builder
     */
    public Builder deleteProjectWatches(Collection<ProjectWatchKey> projectWatches) {
      deletedProjectWatchesBuilder().addAll(projectWatches);
      return this;
    }

    /**
     * Sets the general preferences for the account.
     *
     * <p>Updates any preference that is non-null in the provided GeneralPreferencesInfo.
     *
     * @param generalPreferences the general preferences that should be set
     * @return the builder
     */
    public abstract Builder setGeneralPreferences(GeneralPreferencesInfo generalPreferences);

    /**
     * Sets the diff preferences for the account.
     *
     * <p>Updates any preference that is non-null in the provided DiffPreferencesInfo.
     *
     * @param diffPreferences the diff preferences that should be set
     * @return the builder
     */
    public abstract Builder setDiffPreferences(DiffPreferencesInfo diffPreferences);

    /**
     * Sets the edit preferences for the account.
     *
     * <p>Updates any preference that is non-null in the provided EditPreferencesInfo.
     *
     * @param editPreferences the edit preferences that should be set
     * @return the builder
     */
    public abstract Builder setEditPreferences(EditPreferencesInfo editPreferences);

    /** Builds the instance. */
    public abstract AccountDelta build();

    /**
     * Wrapper for {@link Builder} that converts {@code null} string arguments to empty strings for
     * all setter methods. This allows us to treat setter invocations with a {@code null} string
     * argument as signal to unset the corresponding field. E.g. for a builder method {@code
     * setX(String)} the following semantics apply:
     *
     * <ul>
     *   <li>Method is not invoked: X stays unchanged, X is stored as {@code Optional.empty()}.
     *   <li>Argument is a non-empty string Y: X is updated to the Y, X is stored as {@code
     *       Optional.of(Y)}.
     *   <li>Argument is an empty string: X is unset, X is stored as {@code Optional.of("")}
     *   <li>Argument is {@code null}: X is unset, X is stored as {@code Optional.of("")} (since the
     *       wrapper converts {@code null} to an empty string)
     * </ul>
     *
     * Without the wrapper calling {@code setX(null)} would fail with a {@link
     * NullPointerException}. Hence all callers would need to take care to call {@link
     * Strings#nullToEmpty(String)} for all string arguments and likely it would be forgotten in
     * some places.
     *
     * <p>This means the stored values are interpreted like this:
     *
     * <ul>
     *   <li>{@code Optional.empty()}: property stays unchanged
     *   <li>{@code Optional.of(<non-empty-string>)}: property is updated
     *   <li>{@code Optional.of("")}: property is unset
     * </ul>
     *
     * This wrapper forwards all method invocations to the wrapped {@link Builder} instance that was
     * created by AutoValue. For methods that return the AutoValue {@link Builder} instance the
     * return value is replaced with the wrapper instance so that all chained calls go through the
     * wrapper.
     */
    private static class WrapperThatConvertsNullStringArgsToEmptyStrings extends Builder {
      private final Builder delegate;

      private WrapperThatConvertsNullStringArgsToEmptyStrings(Builder delegate) {
        this.delegate = delegate;
      }

      @Override
      public Builder setFullName(String fullName) {
        delegate.setFullName(Strings.nullToEmpty(fullName));
        return this;
      }

      @Override
      public Builder setDisplayName(String displayName) {
        delegate.setDisplayName(Strings.nullToEmpty(displayName));
        return this;
      }

      @Override
      public Builder setPreferredEmail(String preferredEmail) {
        delegate.setPreferredEmail(Strings.nullToEmpty(preferredEmail));
        return this;
      }

      @Override
      public Builder setActive(boolean active) {
        delegate.setActive(active);
        return this;
      }

      @Override
      public Builder setStatus(String status) {
        delegate.setStatus(Strings.nullToEmpty(status));
        return this;
      }

      @Override
      public AccountDelta build() {
        return delegate.build();
      }

      @Override
      ImmutableSet.Builder<ExternalId> createdExternalIdsBuilder() {
        return delegate.createdExternalIdsBuilder();
      }

      @Override
      public Builder addExternalIds(Collection<ExternalId> extIds) {
        delegate.addExternalIds(extIds);
        return this;
      }

      @Override
      ImmutableSet.Builder<ExternalId> updatedExternalIdsBuilder() {
        return delegate.updatedExternalIdsBuilder();
      }

      @Override
      public Builder updateExternalIds(Collection<ExternalId> extIds) {
        delegate.updateExternalIds(extIds);
        return this;
      }

      @Override
      ImmutableSet.Builder<ExternalId> deletedExternalIdsBuilder() {
        return delegate.deletedExternalIdsBuilder();
      }

      @Override
      public Builder deleteExternalIds(Collection<ExternalId> extIds) {
        delegate.deleteExternalIds(extIds);
        return this;
      }

      @Override
      ImmutableMap.Builder<ProjectWatchKey, Set<NotifyType>> updatedProjectWatchesBuilder() {
        return delegate.updatedProjectWatchesBuilder();
      }

      @Override
      public Builder updateProjectWatches(Map<ProjectWatchKey, Set<NotifyType>> projectWatches) {
        delegate.updateProjectWatches(projectWatches);
        return this;
      }

      @Override
      ImmutableSet.Builder<ProjectWatchKey> deletedProjectWatchesBuilder() {
        return delegate.deletedProjectWatchesBuilder();
      }

      @Override
      public Builder deleteProjectWatches(Collection<ProjectWatchKey> projectWatches) {
        delegate.deleteProjectWatches(projectWatches);
        return this;
      }

      @Override
      public Builder setGeneralPreferences(GeneralPreferencesInfo generalPreferences) {
        delegate.setGeneralPreferences(generalPreferences);
        return this;
      }

      @Override
      public Builder setDiffPreferences(DiffPreferencesInfo diffPreferences) {
        delegate.setDiffPreferences(diffPreferences);
        return this;
      }

      @Override
      public Builder setEditPreferences(EditPreferencesInfo editPreferences) {
        delegate.setEditPreferences(editPreferences);
        return this;
      }
    }
  }
}
