// 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.googlesource.gerrit.plugins.simplesubmitrules.rules;

import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.rules.SubmitRule;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.simplesubmitrules.SimpleSubmitRulesConfig;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Simple rule: require a non-author approval or block submission */
public class RequireNonAuthorApprovalRule implements SubmitRule {
  private static final Logger log = LoggerFactory.getLogger(RequireNonAuthorApprovalRule.class);
  private static final String E_UNABLE_TO_FETCH_CHANGE_OWNER = "Unable to fetch the change owner";
  private static final String E_UNABLE_TO_FETCH_LABELS =
      "Unable to fetch labels and approvals for the change";
  private final ProjectCache projectCache;

  @Inject
  public RequireNonAuthorApprovalRule(ProjectCache projectCache) {
    this.projectCache = projectCache;
  }

  @Override
  public Collection<SubmitRecord> evaluate(ChangeData cd, SubmitRuleOptions options) {
    ProjectState projectState = projectCache.get(cd.project());
    Config config = projectState.getConfig(ProjectConfig.PROJECT_CONFIG).getWithInheritance();

    Account.Id owner;
    try {
      owner = cd.change().getOwner();
    } catch (OrmException e) {
      log.error(E_UNABLE_TO_FETCH_CHANGE_OWNER, e);

      SubmitRecord submitRecord = new SubmitRecord();
      submitRecord.errorMessage = E_UNABLE_TO_FETCH_CHANGE_OWNER;
      submitRecord.status = SubmitRecord.Status.RULE_ERROR;
      return Collections.singletonList(submitRecord);
    }

    List<LabelType> labelTypes;
    List<PatchSetApproval> approvals;
    try {
      labelTypes = cd.getLabelTypes().getLabelTypes();
      approvals = cd.currentApprovals();
    } catch (OrmException e) {
      log.error(E_UNABLE_TO_FETCH_LABELS, e);

      SubmitRecord submitRecord = new SubmitRecord();
      submitRecord.errorMessage = E_UNABLE_TO_FETCH_LABELS;
      submitRecord.status = SubmitRecord.Status.RULE_ERROR;

      return Collections.singletonList(submitRecord);
    }

    SubmitRecord submitRecord = new SubmitRecord();
    submitRecord.status = SubmitRecord.Status.OK;
    submitRecord.labels = new ArrayList<>(labelTypes.size());

    for (LabelType t : labelTypes) {
      if (!config.getBoolean(
          t.getName(), SimpleSubmitRulesConfig.KEY_REQUIRE_NON_AUTHOR_APPROVAL, false)) {
        // The default rules are enough in this case.
        continue;
      }

      LabelFunction labelFunction = t.getFunction();
      if (labelFunction == null) {
        continue;
      }

      Collection<PatchSetApproval> approvalsForLabel = getApprovalsForLabel(approvals, t, owner);
      SubmitRecord.Label label = labelFunction.check(t, approvalsForLabel);

      switch (label.status) {
        case OK:
        case MAY:
          break;

        case NEED:
        case REJECT:
        case IMPOSSIBLE:
          submitRecord.labels.add(label);
          submitRecord.status = SubmitRecord.Status.NOT_READY;
          break;
      }
    }

    if (submitRecord.labels.isEmpty()) {
      return Collections.emptyList();
    }

    return Collections.singletonList(submitRecord);
  }

  /**
   * Returns the approvals for a given label, for everyone except from `user`, except if the vote is
   * negative.
   */
  @VisibleForTesting
  static Collection<PatchSetApproval> getApprovalsForLabel(
      Collection<PatchSetApproval> approvals, LabelType t, Account.Id user) {
    return approvals
        .stream()
        .filter(input -> input.getValue() < 0 || !input.getAccountId().equals(user))
        .filter(input -> input.getLabel().equals(t.getLabelId().get()))
        .collect(Collectors.toList());
  }
}
