// Copyright (C) 2018 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.change;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.AddReviewerResult;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.ReviewerInfo;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.mail.Address;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.group.GroupResolver;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.Context;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;

public class ReviewerAdder {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static final int DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK = 10;
  public static final int DEFAULT_MAX_REVIEWERS = 20;

  public enum FailureBehavior {
    FAIL,
    IGNORE;
  }

  private enum FailureType {
    NOT_FOUND,
    OTHER;
  }

  // TODO(dborowitz): Subclassing is not the right way to do this. We should instead use an internal
  // type in the public interfaces of ReviewerAdder, rather than passing around the REST API type
  // internally.
  public static class InternalAddReviewerInput extends AddReviewerInput {
    /**
     * Behavior when identifying reviewers fails for any reason <em>besides</em> the input not
     * resolving to an account/group/email.
     */
    public FailureBehavior otherFailureBehavior = FailureBehavior.FAIL;
  }

  public static InternalAddReviewerInput newAddReviewerInput(
      Account.Id reviewer, ReviewerState state, NotifyHandling notify) {
    // AccountResolver always resolves by ID if the input string is numeric.
    return newAddReviewerInput(reviewer.toString(), state, notify);
  }

  public static InternalAddReviewerInput newAddReviewerInput(
      String reviewer, ReviewerState state, NotifyHandling notify) {
    InternalAddReviewerInput in = new InternalAddReviewerInput();
    in.reviewer = reviewer;
    in.state = state;
    in.notify = notify;
    return in;
  }

  public static Optional<InternalAddReviewerInput> newAddReviewerInputFromCommitIdentity(
      Change change, @Nullable Account.Id accountId, NotifyHandling notify) {
    if (accountId == null || accountId.equals(change.getOwner())) {
      // If git ident couldn't be resolved to a user, or if it's not forged, do nothing.
      return Optional.empty();
    }

    InternalAddReviewerInput in = new InternalAddReviewerInput();
    in.reviewer = accountId.toString();
    in.state = REVIEWER;
    in.notify = notify;
    in.otherFailureBehavior = FailureBehavior.IGNORE;
    return Optional.of(in);
  }

  private final AccountResolver accountResolver;
  private final PermissionBackend permissionBackend;
  private final GroupResolver groupResolver;
  private final GroupMembers groupMembers;
  private final AccountLoader.Factory accountLoaderFactory;
  private final Config cfg;
  private final ReviewerJson json;
  private final ProjectCache projectCache;
  private final Provider<AnonymousUser> anonymousProvider;
  private final AddReviewersOp.Factory addReviewersOpFactory;
  private final OutgoingEmailValidator validator;

  @Inject
  ReviewerAdder(
      AccountResolver accountResolver,
      PermissionBackend permissionBackend,
      GroupResolver groupResolver,
      GroupMembers groupMembers,
      AccountLoader.Factory accountLoaderFactory,
      @GerritServerConfig Config cfg,
      ReviewerJson json,
      ProjectCache projectCache,
      Provider<AnonymousUser> anonymousProvider,
      AddReviewersOp.Factory addReviewersOpFactory,
      OutgoingEmailValidator validator) {
    this.accountResolver = accountResolver;
    this.permissionBackend = permissionBackend;
    this.groupResolver = groupResolver;
    this.groupMembers = groupMembers;
    this.accountLoaderFactory = accountLoaderFactory;
    this.cfg = cfg;
    this.json = json;
    this.projectCache = projectCache;
    this.anonymousProvider = anonymousProvider;
    this.addReviewersOpFactory = addReviewersOpFactory;
    this.validator = validator;
  }

  /**
   * Prepare application of a single {@link AddReviewerInput}.
   *
   * @param notes change notes.
   * @param user user performing the reviewer addition.
   * @param input input describing user or group to add as a reviewer.
   * @param allowGroup whether to allow
   * @return handle describing the addition operation. If the {@code op} field is present, this
   *     operation may be added to a {@code BatchUpdate}. Otherwise, the {@code error} field
   *     contains information about an error that occurred
   * @throws IOException
   * @throws PermissionBackendException
   * @throws ConfigInvalidException
   */
  public ReviewerAddition prepare(
      ChangeNotes notes, CurrentUser user, AddReviewerInput input, boolean allowGroup)
      throws IOException, PermissionBackendException, ConfigInvalidException {
    requireNonNull(input.reviewer);
    boolean confirmed = input.confirmed();
    boolean allowByEmail =
        projectCache
            .checkedGet(notes.getProjectName())
            .is(BooleanProjectConfig.ENABLE_REVIEWER_BY_EMAIL);

    ReviewerAddition byAccountId = addByAccountId(input, notes, user);

    ReviewerAddition wholeGroup = null;
    if (!byAccountId.exactMatchFound) {
      wholeGroup = addWholeGroup(input, notes, user, confirmed, allowGroup, allowByEmail);
      if (wholeGroup != null && wholeGroup.exactMatchFound) {
        return wholeGroup;
      }
    }

    if (wholeGroup != null
        && byAccountId.failureType == FailureType.NOT_FOUND
        && wholeGroup.failureType == FailureType.NOT_FOUND) {
      return fail(
          byAccountId.input,
          FailureType.NOT_FOUND,
          byAccountId.result.error + "\n" + wholeGroup.result.error);
    }

    if (byAccountId.failureType != FailureType.NOT_FOUND) {
      return byAccountId;
    }
    if (wholeGroup != null) {
      return wholeGroup;
    }

    return addByEmail(input, notes, user);
  }

  public ReviewerAddition ccCurrentUser(CurrentUser user, RevisionResource revision) {
    return new ReviewerAddition(
        newAddReviewerInput(user.getUserName().orElse(null), CC, NotifyHandling.NONE),
        revision.getNotes(),
        revision.getUser(),
        ImmutableSet.of(user.getAccountId()),
        null,
        true,
        false);
  }

  @Nullable
  private ReviewerAddition addByAccountId(
      AddReviewerInput input, ChangeNotes notes, CurrentUser user)
      throws PermissionBackendException, IOException, ConfigInvalidException {
    IdentifiedUser reviewerUser;
    boolean exactMatchFound = false;
    try {
      reviewerUser = accountResolver.resolve(input.reviewer).asUniqueUser();
      if (input.reviewer.equalsIgnoreCase(reviewerUser.getName())
          || input.reviewer.equals(String.valueOf(reviewerUser.getAccountId()))) {
        exactMatchFound = true;
      }
    } catch (UnprocessableEntityException e) {
      // Caller might choose to ignore this NOT_FOUND result if they find another result e.g. by
      // group, but if not, the error message will be useful.
      return fail(input, FailureType.NOT_FOUND, e.getMessage());
    }

    if (isValidReviewer(notes.getChange().getDest(), reviewerUser.getAccount())) {
      return new ReviewerAddition(
          input,
          notes,
          user,
          ImmutableSet.of(reviewerUser.getAccountId()),
          null,
          exactMatchFound,
          false);
    }
    return fail(
        input,
        FailureType.OTHER,
        MessageFormat.format(ChangeMessages.get().reviewerCantSeeChange, input.reviewer));
  }

  @Nullable
  private ReviewerAddition addWholeGroup(
      AddReviewerInput input,
      ChangeNotes notes,
      CurrentUser user,
      boolean confirmed,
      boolean allowGroup,
      boolean allowByEmail)
      throws IOException, PermissionBackendException {
    if (!allowGroup) {
      return null;
    }

    GroupDescription.Basic group;
    try {
      // TODO(dborowitz): This currently doesn't work in the push path because InternalGroupBackend
      // depends on the Provider<CurrentUser> which returns anonymous in that path.
      group = groupResolver.parseInternal(input.reviewer);
    } catch (UnprocessableEntityException e) {
      if (!allowByEmail) {
        return fail(
            input,
            FailureType.NOT_FOUND,
            MessageFormat.format(ChangeMessages.get().reviewerNotFoundUserOrGroup, input.reviewer));
      }
      return null;
    }

    if (!isLegalReviewerGroup(group.getGroupUUID())) {
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.get().groupIsNotAllowed, group.getName()));
    }

    Set<Account.Id> reviewers = new HashSet<>();
    Set<Account> members;
    try {
      members = groupMembers.listAccounts(group.getGroupUUID(), notes.getProjectName());
    } catch (NoSuchProjectException e) {
      return fail(input, FailureType.OTHER, e.getMessage());
    }

    // if maxAllowed is set to 0, it is allowed to add any number of
    // reviewers
    int maxAllowed = cfg.getInt("addreviewer", "maxAllowed", DEFAULT_MAX_REVIEWERS);
    if (maxAllowed > 0 && members.size() > maxAllowed) {
      logger.atFine().log(
          "Adding %d group members is not allowed (maxAllowed = %d)", members.size(), maxAllowed);
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.get().groupHasTooManyMembers, group.getName()));
    }

    // if maxWithoutCheck is set to 0, we never ask for confirmation
    int maxWithoutConfirmation =
        cfg.getInt("addreviewer", "maxWithoutConfirmation", DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK);
    if (!confirmed && maxWithoutConfirmation > 0 && members.size() > maxWithoutConfirmation) {
      logger.atFine().log(
          "Adding %d group members as reviewer requires confirmation (maxWithoutConfirmation = %d)",
          members.size(), maxWithoutConfirmation);
      return fail(
          input,
          FailureType.OTHER,
          true,
          MessageFormat.format(
              ChangeMessages.get().groupManyMembersConfirmation, group.getName(), members.size()));
    }

    for (Account member : members) {
      if (isValidReviewer(notes.getChange().getDest(), member)) {
        reviewers.add(member.id());
      }
    }

    return new ReviewerAddition(input, notes, user, reviewers, null, true, true);
  }

  @Nullable
  private ReviewerAddition addByEmail(AddReviewerInput input, ChangeNotes notes, CurrentUser user)
      throws PermissionBackendException {
    try {
      permissionBackend.user(anonymousProvider.get()).change(notes).check(ChangePermission.READ);
    } catch (AuthException e) {
      return fail(
          input,
          FailureType.OTHER,
          MessageFormat.format(ChangeMessages.get().reviewerCantSeeChange, input.reviewer));
    }

    Address adr = Address.tryParse(input.reviewer);
    if (adr == null || !validator.isValid(adr.getEmail())) {
      return fail(
          input,
          FailureType.NOT_FOUND,
          MessageFormat.format(ChangeMessages.get().reviewerInvalid, input.reviewer));
    }
    return new ReviewerAddition(input, notes, user, null, ImmutableList.of(adr), true, false);
  }

  private boolean isValidReviewer(BranchNameKey branch, Account member)
      throws PermissionBackendException {
    try {
      // Check ref permission instead of change permission, since change permissions take into
      // account the private bit, whereas adding a user as a reviewer is explicitly allowing them to
      // see private changes.
      permissionBackend.absentUser(member.id()).ref(branch).check(RefPermission.READ);
      return true;
    } catch (AuthException e) {
      return false;
    }
  }

  private ReviewerAddition fail(AddReviewerInput input, FailureType failureType, String error) {
    return fail(input, failureType, false, error);
  }

  private ReviewerAddition fail(
      AddReviewerInput input, FailureType failureType, boolean confirm, String error) {
    ReviewerAddition addition = new ReviewerAddition(input, failureType);
    addition.result.confirm = confirm ? true : null;
    addition.result.error = error;
    return addition;
  }

  public class ReviewerAddition {
    public final AddReviewerResult result;
    @Nullable public final AddReviewersOp op;
    public final ImmutableSet<Account.Id> reviewers;
    public final ImmutableSet<Address> reviewersByEmail;
    @Nullable final IdentifiedUser caller;
    final boolean exactMatchFound;
    private final AddReviewerInput input;
    @Nullable private final FailureType failureType;

    private ReviewerAddition(AddReviewerInput input, FailureType failureType) {
      this.input = input;
      this.failureType = requireNonNull(failureType);
      result = new AddReviewerResult(input.reviewer);
      op = null;
      reviewers = ImmutableSet.of();
      reviewersByEmail = ImmutableSet.of();
      caller = null;
      exactMatchFound = false;
    }

    private ReviewerAddition(
        AddReviewerInput input,
        ChangeNotes notes,
        CurrentUser caller,
        @Nullable Iterable<Account.Id> reviewers,
        @Nullable Iterable<Address> reviewersByEmail,
        boolean exactMatchFound,
        boolean forGroup) {
      checkArgument(
          reviewers != null || reviewersByEmail != null,
          "must have either reviewers or reviewersByEmail");

      this.input = input;
      this.failureType = null;
      result = new AddReviewerResult(input.reviewer);
      // Always silently ignore adding the owner as any type of reviewer on their own change. They
      // may still be implicitly added as a reviewer if they vote, but not via the reviewer API.
      this.reviewers = omitOwner(notes, reviewers);
      this.reviewersByEmail =
          reviewersByEmail == null ? ImmutableSet.of() : ImmutableSet.copyOf(reviewersByEmail);
      this.caller = caller.asIdentifiedUser();
      op = addReviewersOpFactory.create(this.reviewers, this.reviewersByEmail, state(), forGroup);
      this.exactMatchFound = exactMatchFound;
    }

    private ImmutableSet<Account.Id> omitOwner(ChangeNotes notes, Iterable<Account.Id> reviewers) {
      return reviewers != null
          ? Streams.stream(reviewers)
              .filter(id -> !id.equals(notes.getChange().getOwner()))
              .collect(toImmutableSet())
          : ImmutableSet.of();
    }

    public void gatherResults(ChangeData cd) throws PermissionBackendException {
      checkState(op != null, "addition did not result in an update op");
      checkState(op.getResult() != null, "op did not return a result");

      // Generate result details and fill AccountLoader. This occurs outside
      // the Op because the accounts are in a different table.
      AddReviewersOp.Result opResult = op.getResult();
      if (state() == CC) {
        result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size());
        for (Account.Id accountId : opResult.addedCCs()) {
          result.ccs.add(json.format(new ReviewerInfo(accountId.get()), accountId, cd));
        }
        accountLoaderFactory.create(true).fill(result.ccs);
        for (Address a : opResult.addedCCsByEmail()) {
          result.ccs.add(new AccountInfo(a.getName(), a.getEmail()));
        }
      } else {
        result.reviewers = Lists.newArrayListWithCapacity(opResult.addedReviewers().size());
        for (PatchSetApproval psa : opResult.addedReviewers()) {
          // New reviewers have value 0, don't bother normalizing.
          result.reviewers.add(
              json.format(
                  new ReviewerInfo(psa.accountId().get()),
                  psa.accountId(),
                  cd,
                  ImmutableList.of(psa)));
        }
        accountLoaderFactory.create(true).fill(result.reviewers);
        for (Address a : opResult.addedReviewersByEmail()) {
          result.reviewers.add(ReviewerInfo.byEmail(a.getName(), a.getEmail()));
        }
      }
    }

    public ReviewerState state() {
      return input.state();
    }

    public boolean isFailure() {
      return failureType != null;
    }

    public boolean isIgnorableFailure() {
      checkState(failureType != null);
      FailureBehavior behavior =
          (input instanceof InternalAddReviewerInput)
              ? ((InternalAddReviewerInput) input).otherFailureBehavior
              : FailureBehavior.FAIL;
      return failureType == FailureType.OTHER && behavior == FailureBehavior.IGNORE;
    }
  }

  public static boolean isLegalReviewerGroup(AccountGroup.UUID groupUUID) {
    return !SystemGroupBackend.isSystemGroup(groupUUID);
  }

  public ReviewerAdditionList prepare(
      ChangeNotes notes,
      CurrentUser user,
      Iterable<? extends AddReviewerInput> inputs,
      boolean allowGroup)
      throws IOException, PermissionBackendException, ConfigInvalidException {
    // Process CC ops before reviewer ops, so a user that appears in both lists ends up as a
    // reviewer; the last call to ChangeUpdate#putReviewer wins. This can happen if the caller
    // specifies the same string twice, or less obviously if they specify multiple groups with
    // overlapping members.
    // TODO(dborowitz): Consider changing interface to allow excluding reviewers that were
    // previously processed, to proactively prevent overlap so we don't have to rely on this subtle
    // behavior.
    ImmutableList<AddReviewerInput> sorted =
        Streams.stream(inputs)
            .sorted(
                comparing(
                    AddReviewerInput::state,
                    Ordering.explicit(ReviewerState.CC, ReviewerState.REVIEWER)))
            .collect(toImmutableList());
    List<ReviewerAddition> additions = new ArrayList<>();
    for (AddReviewerInput input : sorted) {
      ReviewerAddition addition = prepare(notes, user, input, allowGroup);
      if (addition.op != null) {
        // Assume any callers preparing a list of batch insertions are handling their own email.
        addition.op.suppressEmail();
      }
      additions.add(addition);
    }
    return new ReviewerAdditionList(additions);
  }

  // TODO(dborowitz): This class works, but ultimately feels wrong. It seems like an op but isn't
  // really an op, it's a collection of ops, and it's only called from the body of other ops. We
  // could make this class an op, but we would still have AddReviewersOp. Better would probably be
  // to design a single op that supports combining multiple AddReviewerInputs together. That would
  // probably also subsume the Addition class itself, which would be a good thing.
  public static class ReviewerAdditionList {
    private final ImmutableList<ReviewerAddition> additions;

    private ReviewerAdditionList(List<ReviewerAddition> additions) {
      this.additions = ImmutableList.copyOf(additions);
    }

    public ImmutableList<ReviewerAddition> getFailures() {
      return additions.stream()
          .filter(a -> a.isFailure() && !a.isIgnorableFailure())
          .collect(toImmutableList());
    }

    // We never call updateRepo on the addition ops, which is only ok because it's a no-op.

    public void updateChange(ChangeContext ctx, PatchSet patchSet)
        throws RestApiException, IOException {
      for (ReviewerAddition addition : additions()) {
        addition.op.setPatchSet(patchSet);
        addition.op.updateChange(ctx);
      }
    }

    public void postUpdate(Context ctx) throws Exception {
      for (ReviewerAddition addition : additions()) {
        if (addition.op != null) {
          addition.op.postUpdate(ctx);
        }
      }
    }

    public <T> ImmutableSet<T> flattenResults(
        Function<AddReviewersOp.Result, ? extends Collection<T>> func) {
      additions()
          .forEach(
              a ->
                  checkArgument(
                      a.op != null && a.op.getResult() != null, "missing result on %s", a));
      return additions().stream()
          .map(a -> a.op.getResult())
          .map(func)
          .flatMap(Collection::stream)
          .collect(toImmutableSet());
    }

    private ImmutableList<ReviewerAddition> additions() {
      return additions.stream()
          .filter(
              a -> {
                if (a.isFailure()) {
                  if (a.isIgnorableFailure()) {
                    return false;
                  }
                  // Shouldn't happen, caller should have checked that there were no errors.
                  throw new IllegalStateException("error in addition: " + a.result.error);
                }
                return true;
              })
          .collect(toImmutableList());
    }
  }
}
