// Copyright (C) 2017 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.googlesource.gerrit.plugins.findowners;

import static java.util.stream.Collectors.toList;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Status;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.config.PluginConfigFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.eclipse.jgit.lib.Repository;

/** Create and return OWNERS info when "Find Owners" button is clicked. */
class Action implements RestReadView<RevisionResource>, UiAction<RevisionResource> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private AccountCache accountCache;
  private Emails emails;
  private ChangeData.Factory changeDataFactory;
  private GitRepositoryManager repoManager;
  private Provider<CurrentUser> userProvider;
  private SchemaFactory<ReviewDb> reviewDbProvider;
  private ProjectCache projectCache;

  static class Parameters {
    Boolean debug; // REST API "debug" parameter, or null
    Boolean nocache; // REST API "nocache" parameter, or null
    Integer patchset; // REST API "patchset" parameter, or null
  }

  @Inject
  Action(
      @PluginName String pluginName,
      PluginConfigFactory configFactory,
      Provider<CurrentUser> userProvider,
      SchemaFactory<ReviewDb> reviewDbProvider,
      ChangeData.Factory changeDataFactory,
      AccountCache accountCache,
      Emails emails,
      GitRepositoryManager repoManager,
      ProjectCache projectCache) {
    this.userProvider = userProvider;
    this.reviewDbProvider = reviewDbProvider;
    this.changeDataFactory = changeDataFactory;
    this.accountCache = accountCache;
    this.emails = emails;
    this.repoManager = repoManager;
    this.projectCache = projectCache;
    Config.setVariables(pluginName, configFactory);
    Cache.getInstance(); // Create a single Cache.
  }

  @VisibleForTesting
  Action() {}

  private String getUserName() {
    if (userProvider != null && userProvider.get().getUserName().isPresent()) {
      return userProvider.get().getUserName().get();
    }
    return "?";
  }

  private List<OwnerInfo> getOwners(OwnersDb db, Collection<String> files) {
    Map<String, OwnerWeights> weights = new HashMap<>();
    db.findOwners(files, weights, new ArrayList<>());
    List<OwnerInfo> result = new ArrayList<>();
    Set<String> emails = new HashSet<>();
    for (String key : OwnerWeights.sortKeys(weights)) {
      if (!emails.contains(key)) {
        result.add(new OwnerInfo(key, weights.get(key).getLevelCounts()));
        emails.add(key);
      }
    }
    return result;
  }

  @Override
  public Response<RestResult> apply(RevisionResource rev)
      throws IOException, OrmException, BadRequestException {
    return apply(rev.getChangeResource(), new Parameters());
  }

  // Used by both Action.apply and GetOwners.apply.
  public Response<RestResult> apply(ChangeResource rsrc, Parameters params)
      throws IOException, OrmException, BadRequestException {
    try (ReviewDb reviewDb = reviewDbProvider.open()) {
      return apply(reviewDb, rsrc, params);
    }
  }

  // Used by integration tests, because they do not have ReviewDb Provider.
  public Response<RestResult> apply(ReviewDb reviewDb, ChangeResource rsrc, Parameters params)
      throws IOException, OrmException, BadRequestException {
    Change c = rsrc.getChange();
    try (Repository repo = repoManager.openRepository(c.getProject())) {
      ChangeData changeData = changeDataFactory.create(reviewDb, c);
      return getChangeData(repo, params, changeData);
    }
  }

  /** Returns reviewer emails got from ChangeData. */
  static List<String> getReviewers(ChangeData changeData, AccountCache accountCache) {
    try {
      // Reviewers may have no preferred email, skip them if the preferred email is not set.
      return changeData
          .reviewers()
          .all()
          .stream()
          .map(accountCache::get)
          .flatMap(Streams::stream)
          .map(a -> a.getAccount().getPreferredEmail())
          .filter(Objects::nonNull)
          .collect(toList());
    } catch (OrmException e) {
      logger.atSevere().withCause(e).log("Exception for %s", Config.getChangeId(changeData));
      return new ArrayList<>();
    }
  }

  /** Returns the current patchset number or the given patchsetNum if it is valid. */
  static int getValidPatchsetNum(ChangeData changeData, Integer patchsetNum)
      throws OrmException, BadRequestException {
    int patchset = changeData.currentPatchSet().getId().get();
    if (patchsetNum != null) {
      if (patchsetNum < 1 || patchsetNum > patchset) {
        throw new BadRequestException(
            "Invalid patchset parameter: "
                + patchsetNum
                + "; must be 1"
                + ((1 != patchset) ? (" to " + patchset) : ""));
      }
      return patchsetNum;
    }
    return patchset;
  }

  /** REST API to return owners info of a change. */
  public Response<RestResult> getChangeData(
      Repository repository, Parameters params, ChangeData changeData)
      throws OrmException, BadRequestException, IOException {
    int patchset = getValidPatchsetNum(changeData, params.patchset);
    ProjectState projectState = projectCache.get(changeData.project());
    Boolean useCache = params.nocache == null || !params.nocache;
    OwnersDb db = Cache.getInstance().get(
        useCache, projectState, accountCache, emails, repository, changeData, patchset);
    Collection<String> changedFiles = changeData.currentFilePaths();
    Map<String, Set<String>> file2Owners = db.findOwners(changedFiles);

    Boolean addDebugMsg = (params.debug != null) ? params.debug : Config.getAddDebugMsg();
    RestResult obj =
        new RestResult(Config.getMinOwnerVoteLevel(projectState, changeData), addDebugMsg);
    obj.change = changeData.getId().get();
    obj.patchset = patchset;
    obj.ownerRevision = db.revision;
    if (addDebugMsg) {
      obj.dbgmsgs.user = getUserName();
      obj.dbgmsgs.project = changeData.change().getProject().get();
      obj.dbgmsgs.branch = changeData.change().getDest().get();
      obj.dbgmsgs.errors = db.errors;
      obj.dbgmsgs.path2owners = Util.makeSortedMap(db.path2Owners);
      obj.dbgmsgs.owner2paths = Util.makeSortedMap(db.owner2Paths);
      obj.dbgmsgs.logs = db.logs;
    }

    obj.file2owners = Util.makeSortedMap(file2Owners);
    obj.reviewers = getReviewers(changeData, accountCache);
    obj.owners = getOwners(db, changedFiles);
    obj.files = new ArrayList<>(changedFiles);
    return Response.ok(obj);
  }

  @Override
  public Description getDescription(RevisionResource resource) {
    Change change = resource.getChangeResource().getChange();
    ChangeData changeData = null;
    try (ReviewDb reviewDb = reviewDbProvider.open()) {
      changeData = changeDataFactory.create(reviewDb, change);
      if (changeData.change().getDest().get() == null) {
        if (!Checker.isExemptFromOwnerApproval(changeData)) {
          logger.atSevere().log("Cannot get branch of change: %d", changeData.getId().get());
        }
        return null; // no "Find Owners" button
      }
      Status status = resource.getChange().getStatus();
      // Commit message is not used to enable/disable "Find Owners".
      boolean needFindOwners =
          userProvider != null
              && userProvider.get() instanceof IdentifiedUser
              && status != Status.ABANDONED
              && status != Status.MERGED;
      // If alwaysShowButton is true, skip expensive owner lookup.
      if (needFindOwners && !Config.getAlwaysShowButton()) {
        needFindOwners = false; // Show button only if some owner is found.
        try (Repository repo = repoManager.openRepository(change.getProject())) {
          OwnersDb db =
              Cache.getInstance()
                  .get(
                      true, // use cached OwnersDb
                      projectCache.get(resource.getProject()),
                      accountCache,
                      emails,
                      repo,
                      changeData);
          logger.atFiner().log("getDescription db key = %s", db.key);
          needFindOwners = db.getNumOwners() > 0;
        }
      }
      return new Description()
          .setLabel("Find Owners")
          .setTitle("Find owners to add to Reviewers list")
          .setVisible(needFindOwners);
    } catch (IOException | OrmException e) {
      logger.atSevere().withCause(e).log("Exception for %s", Config.getChangeId(changeData));
      throw new IllegalStateException(e);
    }
  }
}
