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

import static com.google.common.flogger.LazyArgs.lazy;
import static java.util.stream.Collectors.toList;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.GroupReference;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountVisibility;
import com.google.gerrit.extensions.common.GroupBaseInfo;
import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.index.IndexConfig;
import com.google.gerrit.index.QueryOptions;
import com.google.gerrit.index.SchemaFieldDefs.SchemaField;
import com.google.gerrit.index.query.FieldBundle;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.index.query.ResultSet;
import com.google.gerrit.index.query.TooManyTermsInQueryException;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountControl;
import com.google.gerrit.server.account.AccountDirectory.FillOptions;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupMembers;
import com.google.gerrit.server.account.ServiceUserClassifier;
import com.google.gerrit.server.change.ReviewerModifier;
import com.google.gerrit.server.index.account.AccountField;
import com.google.gerrit.server.index.account.AccountIndexCollection;
import com.google.gerrit.server.index.account.AccountIndexRewriter;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.account.AccountPredicates;
import com.google.gerrit.server.query.account.AccountQueryBuilder;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;

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

  @Singleton
  private static class Metrics {
    final Timer0 queryAccountsLatency;
    final Timer0 recommendAccountsLatency;
    final Timer0 loadAccountsLatency;
    final Timer0 queryGroupsLatency;
    final Timer0 filterVisibility;

    @Inject
    Metrics(MetricMaker metricMaker) {
      queryAccountsLatency =
          metricMaker.newTimer(
              "reviewer_suggestion/query_accounts",
              new Description("Latency for querying accounts for reviewer suggestion")
                  .setCumulative()
                  .setUnit(Units.MILLISECONDS));
      recommendAccountsLatency =
          metricMaker.newTimer(
              "reviewer_suggestion/recommend_accounts",
              new Description("Latency for recommending accounts for reviewer suggestion")
                  .setCumulative()
                  .setUnit(Units.MILLISECONDS));
      loadAccountsLatency =
          metricMaker.newTimer(
              "reviewer_suggestion/load_accounts",
              new Description("Latency for loading accounts for reviewer suggestion")
                  .setCumulative()
                  .setUnit(Units.MILLISECONDS));
      queryGroupsLatency =
          metricMaker.newTimer(
              "reviewer_suggestion/query_groups",
              new Description("Latency for querying groups for reviewer suggestion")
                  .setCumulative()
                  .setUnit(Units.MILLISECONDS));
      filterVisibility =
          metricMaker.newTimer(
              "reviewer_suggestion/filter_visibility",
              new Description("Latency for removing users that can't see the change")
                  .setCumulative()
                  .setUnit(Units.MILLISECONDS));
    }
  }

  private final AccountVisibility accountVisibility;
  private final AccountLoader.Factory accountLoaderFactory;
  private final AccountQueryBuilder accountQueryBuilder;
  private final AccountIndexRewriter accountIndexRewriter;
  private final GroupBackend groupBackend;
  private final GroupMembers groupMembers;
  private final ReviewerRecommender reviewerRecommender;
  private final Metrics metrics;
  private final AccountIndexCollection accountIndexes;
  private final IndexConfig indexConfig;
  private final AccountControl.Factory accountControlFactory;
  private final Provider<CurrentUser> self;
  private final ServiceUserClassifier serviceUserClassifier;

  @Inject
  ReviewersUtil(
      AccountVisibility accountVisibility,
      AccountLoader.Factory accountLoaderFactory,
      AccountQueryBuilder accountQueryBuilder,
      AccountIndexRewriter accountIndexRewriter,
      GroupBackend groupBackend,
      GroupMembers groupMembers,
      ReviewerRecommender reviewerRecommender,
      Metrics metrics,
      AccountIndexCollection accountIndexes,
      IndexConfig indexConfig,
      AccountControl.Factory accountControlFactory,
      Provider<CurrentUser> self,
      ServiceUserClassifier serviceUserClassifier) {
    this.accountVisibility = accountVisibility;
    this.accountLoaderFactory = accountLoaderFactory;
    this.accountQueryBuilder = accountQueryBuilder;
    this.accountIndexRewriter = accountIndexRewriter;
    this.groupBackend = groupBackend;
    this.groupMembers = groupMembers;
    this.reviewerRecommender = reviewerRecommender;
    this.metrics = metrics;
    this.accountIndexes = accountIndexes;
    this.indexConfig = indexConfig;
    this.accountControlFactory = accountControlFactory;
    this.self = self;
    this.serviceUserClassifier = serviceUserClassifier;
  }

  public interface VisibilityControl {
    boolean isVisibleTo(Account.Id account);
  }

  public List<SuggestedReviewerInfo> suggestReviewers(
      ReviewerState reviewerState,
      @Nullable ChangeNotes changeNotes,
      SuggestReviewers suggestReviewers,
      ProjectState projectState,
      VisibilityControl visibilityControl,
      boolean excludeGroups)
      throws IOException, ConfigInvalidException, PermissionBackendException, BadRequestException {
    CurrentUser currentUser = self.get();
    if (changeNotes != null) {
      logger.atFine().log(
          "Suggesting reviewers for change %s to user %s.",
          changeNotes.getChangeId().get(), currentUser.getLoggableName());
    } else {
      logger.atFine().log(
          "Suggesting default reviewers for project %s to user %s.",
          projectState.getName(), currentUser.getLoggableName());
    }

    String query = suggestReviewers.getQuery();
    logger.atFine().log("Query: %s", query);
    int limit = suggestReviewers.getLimit();

    if (!suggestReviewers.getSuggestAccounts()) {
      logger.atFine().log("Reviewer suggestion is disabled.");
      return Collections.emptyList();
    }
    AccountControl accountControl = accountControlFactory.get();

    if (accountVisibility == AccountVisibility.NONE && !accountControl.canViewAll()) {
      logger.atFine().log(
          "Not suggesting reviewers: accountVisibility = %s and the user does not have %s capability",
          AccountVisibility.NONE, GlobalPermission.VIEW_ALL_ACCOUNTS);
      return Collections.emptyList();
    }

    List<Account.Id> candidateList = new ArrayList<>();
    if (!Strings.isNullOrEmpty(query)) {
      candidateList = suggestAccounts(suggestReviewers);
      logger.atFine().log("Candidate list: %s", candidateList);
    }
    List<Account.Id> sortedRecommendations =
        recommendAccounts(
            reviewerState, changeNotes, suggestReviewers, projectState, candidateList);
    logger.atFine().log("Sorted recommendations: %s", sortedRecommendations);

    // Filter accounts by visibility, skip service users and enforce limit
    List<Account.Id> filteredRecommendations = new ArrayList<>();
    try (Timer0.Context ctx = metrics.filterVisibility.start()) {
      for (Account.Id reviewer : sortedRecommendations) {
        if (filteredRecommendations.size() >= limit) {
          break;
        }
        if (suggestReviewers.isSkipServiceUsers()
            && serviceUserClassifier.isServiceUser(reviewer)) {
          continue;
        }
        // Check if change is visible to reviewer and if the current user can see reviewer
        if (visibilityControl.isVisibleTo(reviewer) && accountControl.canSee(reviewer)) {
          filteredRecommendations.add(reviewer);
        }
      }
    }
    logger.atFine().log("Filtered recommendations: %s", filteredRecommendations);

    List<SuggestedReviewerInfo> suggestedReviewers =
        suggestReviewers(
            suggestReviewers,
            projectState,
            visibilityControl,
            excludeGroups,
            filteredRecommendations);
    logger.atFine().log(
        "Suggested reviewers: %s", lazy(() -> formatSuggestedReviewers(suggestedReviewers)));
    return suggestedReviewers;
  }

  private static Account.Id fromIdField(FieldBundle f, boolean useLegacyNumericFields) {
    if (useLegacyNumericFields) {
      return Account.id(f.<Integer>getValue(AccountField.ID_FIELD_SPEC).intValue());
    }
    return Account.id(Integer.valueOf(f.<String>getValue(AccountField.ID_STR_FIELD_SPEC)));
  }

  // More accounts are suggested here than the requested limit because
  // visibility filtering will be applied later.
  private List<Account.Id> suggestAccounts(SuggestReviewers suggestReviewers)
      throws BadRequestException {
    try (Timer0.Context ctx = metrics.queryAccountsLatency.start()) {
      // For performance reasons we don't use AccountQueryProvider as it would always load the
      // complete account from the cache (or worse, from NoteDb) even though we only need the ID
      // which we can directly get from the returned results.
      Predicate<AccountState> pred =
          Predicate.and(
              AccountPredicates.isActive(),
              accountQueryBuilder.defaultQuery(suggestReviewers.getQuery()));
      logger.atFine().log("accounts index query: %s", pred);
      accountIndexRewriter.validateMaxTermsInQuery(pred);
      boolean useLegacyNumericFields =
          accountIndexes.getSearchIndex().getSchema().hasField(AccountField.ID_FIELD_SPEC);
      SchemaField<AccountState, ?> idField =
          useLegacyNumericFields ? AccountField.ID_FIELD_SPEC : AccountField.ID_STR_FIELD_SPEC;
      ResultSet<FieldBundle> result =
          accountIndexes
              .getSearchIndex()
              .getSource(
                  pred,
                  QueryOptions.create(
                      indexConfig,
                      0,
                      suggestReviewers.getLimit() + 30,
                      ImmutableSet.of(idField.getName())))
              .readRaw();
      List<Account.Id> matches =
          result.toList().stream()
              .map(f -> fromIdField(f, useLegacyNumericFields))
              .collect(toList());
      logger.atFine().log("Matches: %s", matches);
      return matches;
    } catch (TooManyTermsInQueryException e) {
      throw new BadRequestException(e.getMessage());
    } catch (QueryParseException e) {
      logger.atWarning().withCause(e).log("Suggesting accounts failed, return empty result.");
      return ImmutableList.of();
    } catch (StorageException e) {
      if (e.getCause() instanceof TooManyTermsInQueryException) {
        throw new BadRequestException(e.getMessage());
      }
      if (e.getCause() instanceof QueryParseException) {
        return ImmutableList.of();
      }
      throw e;
    }
  }

  private List<SuggestedReviewerInfo> suggestReviewers(
      SuggestReviewers suggestReviewers,
      ProjectState projectState,
      VisibilityControl visibilityControl,
      boolean excludeGroups,
      List<Account.Id> filteredRecommendations)
      throws PermissionBackendException, IOException {
    List<SuggestedReviewerInfo> suggestedReviewers = loadAccounts(filteredRecommendations);

    int limit = suggestReviewers.getLimit();
    if (!excludeGroups
        && suggestedReviewers.size() < limit
        && !Strings.isNullOrEmpty(suggestReviewers.getQuery())) {
      // Add groups at the end as individual accounts are usually more
      // important.
      suggestedReviewers.addAll(
          suggestAccountGroups(
              suggestReviewers,
              projectState,
              visibilityControl,
              limit - suggestedReviewers.size()));
    }

    if (suggestedReviewers.size() > limit) {
      suggestedReviewers = suggestedReviewers.subList(0, limit);
      logger.atFine().log("Limited suggested reviewers to %d accounts.", limit);
    }
    return suggestedReviewers;
  }

  private List<Account.Id> recommendAccounts(
      ReviewerState reviewerState,
      @Nullable ChangeNotes changeNotes,
      SuggestReviewers suggestReviewers,
      ProjectState projectState,
      List<Account.Id> candidateList)
      throws IOException, ConfigInvalidException {
    try (Timer0.Context ctx = metrics.recommendAccountsLatency.start()) {
      return reviewerRecommender.suggestReviewers(
          reviewerState, changeNotes, suggestReviewers.getQuery(), projectState, candidateList);
    }
  }

  private List<SuggestedReviewerInfo> loadAccounts(List<Account.Id> accountIds)
      throws PermissionBackendException {
    Set<FillOptions> fillOptions =
        Sets.union(AccountLoader.DETAILED_OPTIONS, EnumSet.of(FillOptions.SECONDARY_EMAILS));
    AccountLoader accountLoader = accountLoaderFactory.create(fillOptions);

    try (Timer0.Context ctx = metrics.loadAccountsLatency.start()) {
      List<SuggestedReviewerInfo> reviewer =
          accountIds.stream()
              .map(accountLoader::get)
              .filter(Objects::nonNull)
              .map(
                  a -> {
                    SuggestedReviewerInfo info = new SuggestedReviewerInfo();
                    info.account = a;
                    info.count = 1;
                    return info;
                  })
              .collect(toList());
      accountLoader.fill();
      return reviewer;
    }
  }

  private List<SuggestedReviewerInfo> suggestAccountGroups(
      SuggestReviewers suggestReviewers,
      ProjectState projectState,
      VisibilityControl visibilityControl,
      int limit)
      throws IOException {
    try (Timer0.Context ctx = metrics.queryGroupsLatency.start()) {
      List<SuggestedReviewerInfo> groups = new ArrayList<>();
      for (GroupReference g : suggestAccountGroups(suggestReviewers, projectState)) {
        GroupAsReviewer result =
            suggestGroupAsReviewer(
                suggestReviewers, projectState.getProject(), g, visibilityControl);
        if (result.allowed || result.allowedWithConfirmation) {
          GroupBaseInfo info = new GroupBaseInfo();
          info.id = Url.encode(g.getUUID().get());
          info.name = g.getName();
          SuggestedReviewerInfo suggestedReviewerInfo = new SuggestedReviewerInfo();
          suggestedReviewerInfo.group = info;
          suggestedReviewerInfo.count = result.size;
          if (result.allowedWithConfirmation) {
            suggestedReviewerInfo.confirm = true;
          }
          groups.add(suggestedReviewerInfo);
          if (groups.size() >= limit) {
            break;
          }
        }
      }
      return groups;
    }
  }

  private List<GroupReference> suggestAccountGroups(
      SuggestReviewers suggestReviewers, ProjectState projectState) {
    return groupBackend.suggest(suggestReviewers.getQuery(), projectState).stream()
        .limit(suggestReviewers.getLimit())
        .collect(toList());
  }

  private static class GroupAsReviewer {
    boolean allowed;
    boolean allowedWithConfirmation;
    int size;
  }

  private GroupAsReviewer suggestGroupAsReviewer(
      SuggestReviewers suggestReviewers,
      Project project,
      GroupReference group,
      VisibilityControl visibilityControl)
      throws IOException {
    GroupAsReviewer result = new GroupAsReviewer();
    int maxAllowed = suggestReviewers.getMaxAllowed();
    int maxAllowedWithoutConfirmation = suggestReviewers.getMaxAllowedWithoutConfirmation();
    logger.atFine().log("maxAllowedWithoutConfirmation: %s", maxAllowedWithoutConfirmation);

    if (!ReviewerModifier.isLegalReviewerGroup(group.getUUID())) {
      logger.atFine().log("Ignore group %s that is not legal as reviewer", group.getUUID());
      return result;
    }

    try {
      Set<Account> members = groupMembers.listAccounts(group.getUUID(), project.getNameKey());

      if (members.isEmpty()) {
        logger.atFine().log("Ignore group %s since it has no members", group.getUUID());
        return result;
      }

      result.size = members.size();
      if (maxAllowed > 0 && result.size > maxAllowed) {
        return result;
      }

      boolean needsConfirmation =
          maxAllowedWithoutConfirmation > 0 && result.size > maxAllowedWithoutConfirmation;
      if (needsConfirmation) {
        logger.atFine().log(
            "group %s needs confirmation to be added as reviewer, it has %d members",
            group.getUUID(), result.size);
      }

      // require that at least one member in the group can see the change
      for (Account account : members) {
        if (visibilityControl.isVisibleTo(account.id())) {
          if (needsConfirmation) {
            result.allowedWithConfirmation = true;
          } else {
            result.allowed = true;
          }
          logger.atFine().log("Suggest group %s", group.getUUID());
          return result;
        }
      }
      logger.atFine().log(
          "Ignore group %s since none of its members can see the change", group.getUUID());
    } catch (NoSuchProjectException e) {
      return result;
    }

    return result;
  }

  private static String formatSuggestedReviewers(List<SuggestedReviewerInfo> suggestedReviewers) {
    return suggestedReviewers.stream()
        .map(
            r -> {
              if (r.account != null) {
                return "a/" + r.account._accountId;
              } else if (r.group != null) {
                return "g/" + r.group.id;
              } else {
                return "";
              }
            })
        .collect(toList())
        .toString();
  }
}
