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

import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
import static java.util.stream.Collectors.toList;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.AccountDirectory.FillOptions;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.change.ReviewerSuggestion;
import com.google.gerrit.server.change.SuggestReviewers;
import com.google.gerrit.server.change.SuggestedReviewer;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import org.apache.commons.lang.mutable.MutableDouble;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ReviewerRecommender {
  private static final Logger log = LoggerFactory.getLogger(ReviewerRecommender.class);
  private static final double BASE_REVIEWER_WEIGHT = 10;
  private static final double BASE_OWNER_WEIGHT = 1;
  private static final double BASE_COMMENT_WEIGHT = 0.5;
  private static final double[] WEIGHTS =
      new double[] {
        BASE_REVIEWER_WEIGHT, BASE_OWNER_WEIGHT, BASE_COMMENT_WEIGHT,
      };
  private static final long PLUGIN_QUERY_TIMEOUT = 500; //ms

  private final ChangeQueryBuilder changeQueryBuilder;
  private final Config config;
  private final DynamicMap<ReviewerSuggestion> reviewerSuggestionPluginMap;
  private final InternalChangeQuery internalChangeQuery;
  private final WorkQueue workQueue;
  private final Provider<ReviewDb> dbProvider;
  private final ApprovalsUtil approvalsUtil;

  @Inject
  ReviewerRecommender(
      ChangeQueryBuilder changeQueryBuilder,
      DynamicMap<ReviewerSuggestion> reviewerSuggestionPluginMap,
      InternalChangeQuery internalChangeQuery,
      WorkQueue workQueue,
      Provider<ReviewDb> dbProvider,
      ApprovalsUtil approvalsUtil,
      @GerritServerConfig Config config) {
    Set<FillOptions> fillOptions = EnumSet.of(FillOptions.SECONDARY_EMAILS);
    fillOptions.addAll(AccountLoader.DETAILED_OPTIONS);
    this.changeQueryBuilder = changeQueryBuilder;
    this.config = config;
    this.internalChangeQuery = internalChangeQuery;
    this.reviewerSuggestionPluginMap = reviewerSuggestionPluginMap;
    this.workQueue = workQueue;
    this.dbProvider = dbProvider;
    this.approvalsUtil = approvalsUtil;
  }

  public List<Account.Id> suggestReviewers(
      ChangeNotes changeNotes,
      SuggestReviewers suggestReviewers,
      ProjectControl projectControl,
      List<Account.Id> candidateList)
      throws OrmException {
    String query = suggestReviewers.getQuery();
    double baseWeight = config.getInt("addReviewer", "baseWeight", 1);

    Map<Account.Id, MutableDouble> reviewerScores;
    if (Strings.isNullOrEmpty(query)) {
      reviewerScores = baseRankingForEmptyQuery(baseWeight);
    } else {
      reviewerScores = baseRankingForCandidateList(candidateList, projectControl, baseWeight);
    }

    // Send the query along with a candidate list to all plugins and merge the
    // results. Plugins don't necessarily need to use the candidates list, they
    // can also return non-candidate account ids.
    List<Callable<Set<SuggestedReviewer>>> tasks =
        new ArrayList<>(reviewerSuggestionPluginMap.plugins().size());
    List<Double> weights = new ArrayList<>(reviewerSuggestionPluginMap.plugins().size());

    for (DynamicMap.Entry<ReviewerSuggestion> plugin : reviewerSuggestionPluginMap) {
      tasks.add(
          () ->
              plugin
                  .getProvider()
                  .get()
                  .suggestReviewers(
                      projectControl.getProject().getNameKey(),
                      changeNotes.getChangeId(),
                      query,
                      reviewerScores.keySet()));
      String pluginWeight =
          config.getString(
              "addReviewer", plugin.getPluginName() + "-" + plugin.getExportName(), "weight");
      if (Strings.isNullOrEmpty(pluginWeight)) {
        pluginWeight = "1";
      }
      try {
        weights.add(Double.parseDouble(pluginWeight));
      } catch (NumberFormatException e) {
        log.error(
            "Exception while parsing weight for "
                + plugin.getPluginName()
                + "-"
                + plugin.getExportName(),
            e);
        weights.add(1d);
      }
    }

    try {
      List<Future<Set<SuggestedReviewer>>> futures =
          workQueue.getDefaultQueue().invokeAll(tasks, PLUGIN_QUERY_TIMEOUT, TimeUnit.MILLISECONDS);
      Iterator<Double> weightIterator = weights.iterator();
      for (Future<Set<SuggestedReviewer>> f : futures) {
        double weight = weightIterator.next();
        for (SuggestedReviewer s : f.get()) {
          if (reviewerScores.containsKey(s.account)) {
            reviewerScores.get(s.account).add(s.score * weight);
          } else {
            reviewerScores.put(s.account, new MutableDouble(s.score * weight));
          }
        }
      }
    } catch (ExecutionException | InterruptedException e) {
      log.error("Exception while suggesting reviewers", e);
      return ImmutableList.of();
    }

    if (changeNotes != null) {
      // Remove change owner
      reviewerScores.remove(changeNotes.getChange().getOwner());

      // Remove existing reviewers
      reviewerScores
          .keySet()
          .removeAll(approvalsUtil.getReviewers(dbProvider.get(), changeNotes).byState(REVIEWER));
    }

    // Sort results
    Stream<Entry<Account.Id, MutableDouble>> sorted =
        reviewerScores
            .entrySet()
            .stream()
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
    List<Account.Id> sortedSuggestions = sorted.map(Map.Entry::getKey).collect(toList());
    return sortedSuggestions;
  }

  private Map<Account.Id, MutableDouble> baseRankingForEmptyQuery(double baseWeight)
      throws OrmException {
    // Get the user's last 25 changes, check approvals
    try {
      List<ChangeData> result =
          internalChangeQuery
              .setLimit(25)
              .setRequestedFields(ImmutableSet.of(ChangeField.REVIEWER.getName()))
              .query(changeQueryBuilder.owner("self"));
      Map<Account.Id, MutableDouble> suggestions = new HashMap<>();
      for (ChangeData cd : result) {
        for (PatchSetApproval approval : cd.currentApprovals()) {
          Account.Id id = approval.getAccountId();
          if (suggestions.containsKey(id)) {
            suggestions.get(id).add(baseWeight);
          } else {
            suggestions.put(id, new MutableDouble(baseWeight));
          }
        }
      }
      return suggestions;
    } catch (QueryParseException e) {
      // Unhandled, because owner:self will never provoke a QueryParseException
      log.error("Exception while suggesting reviewers", e);
      return ImmutableMap.of();
    }
  }

  private Map<Account.Id, MutableDouble> baseRankingForCandidateList(
      List<Account.Id> candidates, ProjectControl projectControl, double baseWeight)
      throws OrmException {
    // Get each reviewer's activity based on number of applied labels
    // (weighted 10d), number of comments (weighted 0.5d) and number of owned
    // changes (weighted 1d).
    Map<Account.Id, MutableDouble> reviewers = new LinkedHashMap<>();
    if (candidates.size() == 0) {
      return reviewers;
    }
    List<Predicate<ChangeData>> predicates = new ArrayList<>();
    for (Account.Id id : candidates) {
      try {
        Predicate<ChangeData> projectQuery =
            changeQueryBuilder.project(projectControl.getProject().getName());

        // Get all labels for this project and create a compound OR query to
        // fetch all changes where users have applied one of these labels
        List<LabelType> labelTypes = projectControl.getLabelTypes().getLabelTypes();
        List<Predicate<ChangeData>> labelPredicates = new ArrayList<>(labelTypes.size());
        for (LabelType type : labelTypes) {
          labelPredicates.add(changeQueryBuilder.label(type.getName() + ",user=" + id));
        }
        Predicate<ChangeData> reviewerQuery =
            Predicate.and(projectQuery, Predicate.or(labelPredicates));

        Predicate<ChangeData> ownerQuery =
            Predicate.and(projectQuery, changeQueryBuilder.owner(id.toString()));
        Predicate<ChangeData> commentedByQuery =
            Predicate.and(projectQuery, changeQueryBuilder.commentby(id.toString()));

        predicates.add(reviewerQuery);
        predicates.add(ownerQuery);
        predicates.add(commentedByQuery);
        reviewers.put(id, new MutableDouble());
      } catch (QueryParseException e) {
        // Unhandled: If an exception is thrown, we won't increase the
        // candidates's score
        log.error("Exception while suggesting reviewers", e);
      }
    }

    List<List<ChangeData>> result =
        internalChangeQuery.setLimit(25).setRequestedFields(ImmutableSet.of()).query(predicates);

    Iterator<List<ChangeData>> queryResultIterator = result.iterator();
    Iterator<Account.Id> reviewersIterator = reviewers.keySet().iterator();

    int i = 0;
    Account.Id currentId = null;
    while (queryResultIterator.hasNext()) {
      List<ChangeData> currentResult = queryResultIterator.next();
      if (i % WEIGHTS.length == 0) {
        currentId = reviewersIterator.next();
      }

      reviewers.get(currentId).add(WEIGHTS[i % WEIGHTS.length] * baseWeight * currentResult.size());
      i++;
    }
    return reviewers;
  }
}
