// Copyright (C) 2008 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.entities;

import static com.google.gerrit.entities.RefNames.REFS_DRAFT_COMMENTS;
import static com.google.gerrit.entities.RefNames.REFS_STARRED_CHANGES;
import static com.google.gerrit.entities.RefNames.REFS_USERS;

import com.google.auto.value.AutoValue;
import com.google.common.base.MoreObjects;
import com.google.common.primitives.Ints;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.gerrit.common.ConvertibleToProto;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import java.time.Instant;
import java.util.Optional;

/**
 * Information about a single user.
 *
 * <p>A user may have multiple identities they can use to login to Gerrit (see ExternalId), but in
 * such cases they always map back to a single Account entity.
 *
 * <p>Entities "owned" by an Account (that is, their primary key contains the {@link Account.Id} key
 * as part of their key structure):
 *
 * <ul>
 *   <li>ExternalId: OpenID identities and email addresses known to be registered to this user.
 *       Multiple records can exist when the user has more than one public identity, such as a work
 *       and a personal email address.
 *   <li>AccountSshKey: user's public SSH keys, for authentication through the internal SSH daemon.
 *       One record per SSH key uploaded by the user, keys are checked in random order until a match
 *       is found.
 *   <li>{@link DiffPreferencesInfo}: user's preferences for rendering side-to-side and unified diff
 * </ul>
 */
@AutoValue
public abstract class Account {

  /** Placeholder for indicating an account-id that does not correspond to any local account */
  public static final Id UNKNOWN_ACCOUNT_ID = id(0);

  public static Id id(int id) {
    return new AutoValue_Account_Id(id);
  }

  /** Key local to Gerrit to identify a user. */
  @AutoValue
  @ConvertibleToProto
  public abstract static class Id implements Comparable<Id> {
    /** Parse an Account.Id out of a string representation. */
    public static Optional<Id> tryParse(String str) {
      return Optional.ofNullable(Ints.tryParse(str)).map(Account::id);
    }

    @Nullable
    public static Id fromRef(String name) {
      if (name == null) {
        return null;
      }
      if (name.startsWith(REFS_USERS)) {
        return fromRefPart(name.substring(REFS_USERS.length()));
      } else if (name.startsWith(REFS_DRAFT_COMMENTS)) {
        return parseAfterShardedRefPart(name.substring(REFS_DRAFT_COMMENTS.length()));
      } else if (name.startsWith(REFS_STARRED_CHANGES)) {
        return parseAfterShardedRefPart(name.substring(REFS_STARRED_CHANGES.length()));
      }
      return null;
    }

    /**
     * Parse an Account.Id out of a part of a ref-name.
     *
     * @param name a ref name with the following syntax: {@code "34/1234..."}. We assume that the
     *     caller has trimmed any prefix.
     */
    @Nullable
    public static Id fromRefPart(String name) {
      Integer id = RefNames.parseShardedRefPart(name);
      return id != null ? Account.id(id) : null;
    }

    @Nullable
    public static Id parseAfterShardedRefPart(String name) {
      Integer id = RefNames.parseAfterShardedRefPart(name);
      return id != null ? Account.id(id) : null;
    }

    /**
     * Parse an Account.Id out of the last part of a ref name.
     *
     * <p>The input is a ref name of the form {@code ".../1234"}, where the suffix is a non-sharded
     * account ID. Ref names using a sharded ID should use {@link #fromRefPart(String)} instead for
     * greater safety.
     *
     * @param name ref name
     * @return account ID, or null if not numeric.
     */
    @Nullable
    public static Id fromRefSuffix(String name) {
      Integer id = RefNames.parseRefSuffix(name);
      return id != null ? Account.id(id) : null;
    }

    abstract int id();

    public int get() {
      return id();
    }

    @Override
    public final int compareTo(Id o) {
      return Integer.compare(id(), o.id());
    }

    @Override
    public final String toString() {
      return Integer.toString(get());
    }
  }

  public abstract Id id();

  /** Date and time the user registered with the review server. */
  public abstract Instant registeredOn();

  /** Full name of the user ("Given-name Surname" style). */
  @Nullable
  public abstract String fullName();

  /** Optional display name of the user to be shown in the UI. */
  @Nullable
  public abstract String displayName();

  /** Email address the user prefers to be contacted through. */
  @Nullable
  public abstract String preferredEmail();

  /**
   * Is this user inactive? This is used to avoid showing some users (eg. former employees) in
   * auto-suggest.
   */
  public abstract boolean inactive();

  /** The user-settable status of this account (e.g. busy, OOO, available) */
  @Nullable
  public abstract String status();

  /** ID of the user branch from which the account was read. */
  @Nullable
  public abstract String metaId();

  /**
   * A unique tag which identifies the current version of the account.
   *
   * <p>It can be any non-empty string. For open-source gerrit it is the same as metaId; internally
   * in google a different value is assigned.
   *
   * <p>The value can be null only during account updating/creation.
   */
  @Nullable
  public abstract String uniqueTag();

  /**
   * Create a new account.
   *
   * @param newId unique id, see Sequences#nextAccountId().
   * @param registeredOn when the account was registered.
   */
  public static Account.Builder builder(Account.Id newId, Instant registeredOn) {
    return new AutoValue_Account.Builder()
        .setInactive(false)
        .setId(newId)
        .setRegisteredOn(registeredOn);
  }

  /**
   * Formats an account name.
   *
   * <p>The return value goes into NoteDb commits and audit logs, so it should not be changed.
   *
   * <p>This method deliberately does not use {@code Anonymous Coward} because it can be changed
   * using a {@code gerrit.config} option which is a problem for NoteDb commits that still refer to
   * a previously defined value.
   *
   * @return the fullname, if present, otherwise the preferred email, if present, as a last resort a
   *     generic string containing the accountId.
   */
  public String getName() {
    if (fullName() != null) {
      return fullName();
    }
    if (preferredEmail() != null) {
      return preferredEmail();
    }
    return getName(id());
  }

  public static String getName(Account.Id accountId) {
    return "GerritAccount #" + accountId.get();
  }

  /**
   * Get the name and email address.
   *
   * <p>Example output:
   *
   * <ul>
   *   <li>{@code A U. Thor <author@example.com>}: full populated
   *   <li>{@code A U. Thor (12)}: missing email address
   *   <li>{@code Anonymous Coward <author@example.com>}: missing name
   *   <li>{@code Anonymous Coward (12)}: missing name and email address
   * </ul>
   */
  public String getNameEmail(String anonymousCowardName) {
    String name = fullName() != null ? fullName() : anonymousCowardName;
    StringBuilder b = new StringBuilder();
    b.append(name);
    if (preferredEmail() != null) {
      b.append(" <");
      b.append(preferredEmail());
      b.append(">");
    } else {
      b.append(" (");
      b.append(id().get());
      b.append(")");
    }
    return b.toString();
  }

  public boolean isActive() {
    return !inactive();
  }

  public abstract Builder toBuilder();

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Id id();

    abstract Builder setId(Id id);

    public abstract Instant registeredOn();

    abstract Builder setRegisteredOn(Instant registeredOn);

    @Nullable
    public abstract String fullName();

    public abstract Builder setFullName(String fullName);

    @Nullable
    public abstract String displayName();

    public abstract Builder setDisplayName(String displayName);

    @Nullable
    public abstract String preferredEmail();

    public abstract Builder setPreferredEmail(String preferredEmail);

    public abstract boolean inactive();

    public abstract Builder setInactive(boolean inactive);

    @CanIgnoreReturnValue
    public Builder setActive(boolean active) {
      return setInactive(!active);
    }

    @Nullable
    public abstract String status();

    public abstract Builder setStatus(String status);

    @Nullable
    public abstract String metaId();

    public abstract Builder setMetaId(@Nullable String metaId);

    @Nullable
    public abstract String uniqueTag();

    public abstract Builder setUniqueTag(@Nullable String uniqueTag);

    public abstract Account build();
  }

  @Override
  public final String toString() {
    return getName();
  }

  public final String debugString() {
    return MoreObjects.toStringHelper(this)
        .add("id", id())
        .add("registeredOn", registeredOn())
        .add("fullName", fullName())
        .add("displayName", displayName())
        .add("preferredEmail", preferredEmail())
        .add("inactive", inactive())
        .add("status", status())
        .add("metaId", metaId())
        .add("uniqueTag", uniqueTag())
        .toString();
  }
}
