// Copyright (C) 2021 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.account.externalids;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.server.account.HashedPassword;
import com.google.gerrit.server.config.AuthConfig;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;

@Singleton
public class ExternalIdFactory {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
  private final ExternalIdKeyFactory externalIdKeyFactory;
  private AuthConfig authConfig;

  @Inject
  public ExternalIdFactory(ExternalIdKeyFactory externalIdKeyFactory, AuthConfig authConfig) {
    this.externalIdKeyFactory = externalIdKeyFactory;
    this.authConfig = authConfig;
  }

  /**
   * Creates an external ID.
   *
   * @param scheme the scheme name, must not contain colons (':'). E.g. {@link
   *     ExternalId#SCHEME_USERNAME}.
   * @param id the external ID, must not contain colons (':')
   * @param accountId the ID of the account to which the external ID belongs
   * @return the created external ID
   */
  public ExternalId create(String scheme, String id, Account.Id accountId) {
    return create(externalIdKeyFactory.create(scheme, id), accountId, null, null);
  }

  /**
   * Creates an external ID.
   *
   * @param scheme the scheme name, must not contain colons (':'). E.g. {@link
   *     ExternalId#SCHEME_USERNAME}.
   * @param id the external ID, must not contain colons (':')
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @param hashedPassword the hashed password of the external ID, may be {@code null}
   * @return the created external ID
   */
  public ExternalId create(
      String scheme,
      String id,
      Account.Id accountId,
      @Nullable String email,
      @Nullable String hashedPassword) {
    return create(externalIdKeyFactory.create(scheme, id), accountId, email, hashedPassword);
  }

  /**
   * Creates an external ID.
   *
   * @param key the external Id key
   * @param accountId the ID of the account to which the external ID belongs
   * @return the created external ID
   */
  public ExternalId create(ExternalId.Key key, Account.Id accountId) {
    return create(key, accountId, null, null);
  }

  /**
   * Creates an external ID.
   *
   * @param key the external Id key
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @param hashedPassword the hashed password of the external ID, may be {@code null}
   * @return the created external ID
   */
  public ExternalId create(
      ExternalId.Key key,
      Account.Id accountId,
      @Nullable String email,
      @Nullable String hashedPassword) {
    return create(
        key, accountId, Strings.emptyToNull(email), Strings.emptyToNull(hashedPassword), null);
  }

  /**
   * Creates an external ID adding a hashed password computed from a plain password.
   *
   * @param key the external Id key
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @param plainPassword the plain HTTP password, may be {@code null}
   * @return the created external ID
   */
  public ExternalId createWithPassword(
      ExternalId.Key key,
      Account.Id accountId,
      @Nullable String email,
      @Nullable String plainPassword) {
    plainPassword = Strings.emptyToNull(plainPassword);
    String hashedPassword =
        plainPassword != null ? HashedPassword.fromPassword(plainPassword).encode() : null;
    return create(key, accountId, email, hashedPassword);
  }

  /**
   * Create a external ID for a username (scheme "username").
   *
   * @param id the external ID, must not contain colons (':')
   * @param accountId the ID of the account to which the external ID belongs
   * @param plainPassword the plain HTTP password, may be {@code null}
   * @return the created external ID
   */
  public ExternalId createUsername(
      String id, Account.Id accountId, @Nullable String plainPassword) {
    return createWithPassword(
        externalIdKeyFactory.create(ExternalId.SCHEME_USERNAME, id),
        accountId,
        null,
        plainPassword);
  }

  /**
   * Creates an external ID with an email.
   *
   * @param scheme the scheme name, must not contain colons (':'). E.g. {@link
   *     ExternalId#SCHEME_USERNAME}.
   * @param id the external ID, must not contain colons (':')
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @return the created external ID
   */
  public ExternalId createWithEmail(
      String scheme, String id, Account.Id accountId, @Nullable String email) {
    return createWithEmail(externalIdKeyFactory.create(scheme, id), accountId, email);
  }

  /**
   * Creates an external ID with an email.
   *
   * @param key the external Id key
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @return the created external ID
   */
  public ExternalId createWithEmail(
      ExternalId.Key key, Account.Id accountId, @Nullable String email) {
    return create(key, accountId, Strings.emptyToNull(email), null);
  }

  /**
   * Creates an external ID using the `mailto`-scheme.
   *
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @return the created external ID
   */
  public ExternalId createEmail(Account.Id accountId, String email) {
    return createWithEmail(ExternalId.SCHEME_MAILTO, email, accountId, requireNonNull(email));
  }

  ExternalId create(ExternalId extId, @Nullable ObjectId blobId) {
    return create(extId.key(), extId.accountId(), extId.email(), extId.password(), blobId);
  }

  /**
   * Creates an external ID.
   *
   * @param key the external Id key
   * @param accountId the ID of the account to which the external ID belongs
   * @param email the email of the external ID, may be {@code null}
   * @param hashedPassword the hashed password of the external ID, may be {@code null}
   * @param blobId the ID of the note blob in the external IDs branch that stores this external ID.
   *     {@code null} if the external ID was created in code and is not yet stored in Git.
   * @return the created external ID
   */
  public ExternalId create(
      ExternalId.Key key,
      Account.Id accountId,
      @Nullable String email,
      @Nullable String hashedPassword,
      @Nullable ObjectId blobId) {
    return ExternalId.create(
        key, accountId, Strings.emptyToNull(email), Strings.emptyToNull(hashedPassword), blobId);
  }

  /**
   * Parses an external ID from a byte array that contains the external ID as a Git config file
   * text.
   *
   * <p>The Git config must have exactly one externalId subsection with an accountId and optionally
   * email and password:
   *
   * <pre>
   * [externalId "username:jdoe"]
   *   accountId = 1003407
   *   email = jdoe@example.com
   *   password = bcrypt:4:LCbmSBDivK/hhGVQMfkDpA==:XcWn0pKYSVU/UJgOvhidkEtmqCp6oKB7
   * </pre>
   *
   * @param noteId the SHA-1 sum of the external ID used as the note's ID
   * @param raw a byte array that contains the external ID as a Git config file text.
   * @param blobId the ID of the note blob in the external IDs branch that stores this external ID.
   *     {@code null} if the external ID was created in code and is not yet stored in Git.
   * @return the parsed external ID
   */
  public ExternalId parse(String noteId, byte[] raw, ObjectId blobId)
      throws ConfigInvalidException {
    requireNonNull(blobId);

    Config externalIdConfig = new Config();
    try {
      externalIdConfig.fromText(new String(raw, UTF_8));
    } catch (ConfigInvalidException e) {
      throw invalidConfig(noteId, e.getMessage());
    }

    Set<String> externalIdKeys = externalIdConfig.getSubsections(ExternalId.EXTERNAL_ID_SECTION);
    if (externalIdKeys.size() != 1) {
      throw invalidConfig(
          noteId,
          String.format(
              "Expected exactly 1 '%s' section, found %d",
              ExternalId.EXTERNAL_ID_SECTION, externalIdKeys.size()));
    }

    String externalIdKeyStr = Iterables.getOnlyElement(externalIdKeys);
    ExternalId.Key externalIdKey = externalIdKeyFactory.parse(externalIdKeyStr);
    if (externalIdKey == null) {
      throw invalidConfig(noteId, String.format("External ID %s is invalid", externalIdKeyStr));
    }

    if (!externalIdKey.sha1().getName().equals(noteId)) {
      if (!authConfig.isUserNameCaseInsensitiveMigrationMode()) {
        throw invalidConfig(
            noteId,
            String.format(
                "SHA1 of external ID '%s' does not match note ID '%s'", externalIdKeyStr, noteId));
      }

      if (!externalIdKey.caseSensitiveSha1().getName().equals(noteId)) {
        throw invalidConfig(
            noteId,
            String.format(
                "Neither case sensitive nor case insensitive SHA1 of external ID '%s' match note ID '%s'",
                externalIdKeyStr, noteId));
      }
      externalIdKey =
          externalIdKeyFactory.create(externalIdKey.scheme(), externalIdKey.id(), false);
    }

    String email =
        externalIdConfig.getString(
            ExternalId.EXTERNAL_ID_SECTION, externalIdKeyStr, ExternalId.EMAIL_KEY);
    String password =
        externalIdConfig.getString(
            ExternalId.EXTERNAL_ID_SECTION, externalIdKeyStr, ExternalId.PASSWORD_KEY);
    int accountId = readAccountId(noteId, externalIdConfig, externalIdKeyStr);

    return create(
        externalIdKey,
        Account.id(accountId),
        Strings.emptyToNull(email),
        Strings.emptyToNull(password),
        blobId);
  }

  private static int readAccountId(String noteId, Config externalIdConfig, String externalIdKeyStr)
      throws ConfigInvalidException {
    String accountIdStr =
        externalIdConfig.getString(
            ExternalId.EXTERNAL_ID_SECTION, externalIdKeyStr, ExternalId.ACCOUNT_ID_KEY);
    if (accountIdStr == null) {
      throw invalidConfig(
          noteId,
          String.format(
              "Value for '%s.%s.%s' is missing, expected account ID",
              ExternalId.EXTERNAL_ID_SECTION, externalIdKeyStr, ExternalId.ACCOUNT_ID_KEY));
    }

    try {
      int accountId =
          externalIdConfig.getInt(
              ExternalId.EXTERNAL_ID_SECTION, externalIdKeyStr, ExternalId.ACCOUNT_ID_KEY, -1);
      if (accountId < 0) {
        throw invalidConfig(
            noteId,
            String.format(
                "Value %s for '%s.%s.%s' is invalid, expected account ID",
                accountIdStr,
                ExternalId.EXTERNAL_ID_SECTION,
                externalIdKeyStr,
                ExternalId.ACCOUNT_ID_KEY));
      }
      return accountId;
    } catch (IllegalArgumentException e) {
      String msg =
          String.format(
              "Value %s for '%s.%s.%s' is invalid, expected account ID",
              accountIdStr,
              ExternalId.EXTERNAL_ID_SECTION,
              externalIdKeyStr,
              ExternalId.ACCOUNT_ID_KEY);
      logger.atSevere().withCause(e).log(msg);
      throw invalidConfig(noteId, msg);
    }
  }

  private static ConfigInvalidException invalidConfig(String noteId, String message) {
    return new ConfigInvalidException(
        String.format("Invalid external ID config for note '%s': %s", noteId, message));
  }
}
