// Copyright (C) 2009 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.common.base.Preconditions.checkArgument;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.notedb.ReviewerState;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * Utility functions to manipulate patchset approvals.
 * <p>
 * Approvals are overloaded, they represent both approvals and reviewers
 * which should be CCed on a change.  To ensure that reviewers are not lost
 * there must always be an approval on each patchset for each reviewer,
 * even if the reviewer hasn't actually given a score to the change.  To
 * mark the "no score" case, a dummy approval, which may live in any of
 * the available categories, with a score of 0 is used.
 * <p>
 * The methods in this class only modify the gwtorm database.
 */
public class ApprovalsUtil {
  private static Ordering<PatchSetApproval> SORT_APPROVALS = Ordering.natural()
      .onResultOf(new Function<PatchSetApproval, Timestamp>() {
        @Override
        public Timestamp apply(PatchSetApproval a) {
          return a.getGranted();
        }
      });

  public static List<PatchSetApproval> sortApprovals(
      Iterable<PatchSetApproval> approvals) {
    return SORT_APPROVALS.sortedCopy(approvals);
  }

  private static Iterable<PatchSetApproval> filterApprovals(
      Iterable<PatchSetApproval> psas, final Account.Id accountId) {
    return Iterables.filter(psas, new Predicate<PatchSetApproval>() {
      @Override
      public boolean apply(PatchSetApproval input) {
        return Objects.equal(input.getAccountId(), accountId);
      }
    });
  }

  private final NotesMigration migration;

  @VisibleForTesting
  @Inject
  public ApprovalsUtil(NotesMigration migration) {
    this.migration = migration;
  }

  /**
   * Get all reviewers for a change.
   *
   * @param db review database.
   * @param notes change notes.
   * @return multimap of reviewers keyed by state, where each account appears
   *     exactly once in {@link SetMultimap#values()}, and
   *     {@link ReviewerState#REMOVED} is not present.
   * @throws OrmException if reviewers for the change could not be read.
   */
  public ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
      ReviewDb db, ChangeNotes notes) throws OrmException {
    if (!migration.readPatchSetApprovals()) {
      return getReviewers(db.patchSetApprovals().byChange(notes.getChangeId()));
    }
    return notes.load().getReviewers();
  }

  /**
   * Get all reviewers for a change.
   *
   * @param allApprovals all approvals to consider; must all belong to the same
   *     change.
   * @return multimap of reviewers keyed by state, where each account appears
   *     exactly once in {@link SetMultimap#values()}, and
   *     {@link ReviewerState#REMOVED} is not present.
   */
  public ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
      ChangeNotes notes, Iterable<PatchSetApproval> allApprovals)
      throws OrmException {
    if (!migration.readPatchSetApprovals()) {
      return getReviewers(allApprovals);
    }
    return notes.load().getReviewers();
  }

  private static ImmutableSetMultimap<ReviewerState, Account.Id> getReviewers(
      Iterable<PatchSetApproval> allApprovals) {
    PatchSetApproval first = null;
    SetMultimap<ReviewerState, Account.Id> reviewers =
        LinkedHashMultimap.create();
    for (PatchSetApproval psa : allApprovals) {
      if (first == null) {
        first = psa;
      } else {
        checkArgument(
            first.getKey().getParentKey().getParentKey().equals(
              psa.getKey().getParentKey().getParentKey()),
            "multiple change IDs: %s, %s", first.getKey(), psa.getKey());
      }
      Account.Id id = psa.getAccountId();
      if (psa.getValue() != 0) {
        reviewers.put(ReviewerState.REVIEWER, id);
        reviewers.remove(ReviewerState.CC, id);
      } else if (!reviewers.containsEntry(ReviewerState.REVIEWER, id)) {
        reviewers.put(ReviewerState.CC, id);
      }
    }
    return ImmutableSetMultimap.copyOf(reviewers);
  }

  public List<PatchSetApproval> addReviewers(ReviewDb db,
      ChangeUpdate update, LabelTypes labelTypes, Change change, PatchSet ps,
      PatchSetInfo info, Iterable<Account.Id> wantReviewers,
      Collection<Account.Id> existingReviewers) throws OrmException {
    return addReviewers(db, update, labelTypes, change, ps.getId(),
        ps.isDraft(), info.getAuthor().getAccount(),
        info.getCommitter().getAccount(), wantReviewers, existingReviewers);
  }

  public List<PatchSetApproval> addReviewers(ReviewDb db, ChangeNotes notes,
      ChangeUpdate update, LabelTypes labelTypes, Change change,
      Iterable<Account.Id> wantReviewers) throws OrmException {
    PatchSet.Id psId = change.currentPatchSetId();
    return addReviewers(db, update, labelTypes, change, psId, false, null, null,
        wantReviewers, getReviewers(db, notes).values());
  }

  private List<PatchSetApproval> addReviewers(ReviewDb db, ChangeUpdate update,
      LabelTypes labelTypes, Change change, PatchSet.Id psId, boolean isDraft,
      Account.Id authorId, Account.Id committerId,
      Iterable<Account.Id> wantReviewers,
      Collection<Account.Id> existingReviewers) throws OrmException {
    List<LabelType> allTypes = labelTypes.getLabelTypes();
    if (allTypes.isEmpty()) {
      return ImmutableList.of();
    }

    Set<Account.Id> need = Sets.newLinkedHashSet(wantReviewers);
    if (authorId != null && !isDraft) {
      need.add(authorId);
    }

    if (committerId != null && !isDraft) {
      need.add(committerId);
    }
    need.remove(change.getOwner());
    need.removeAll(existingReviewers);
    if (need.isEmpty()) {
      return ImmutableList.of();
    }

    List<PatchSetApproval> cells = Lists.newArrayListWithCapacity(need.size());
    LabelId labelId = Iterables.getLast(allTypes).getLabelId();
    for (Account.Id account : need) {
      cells.add(new PatchSetApproval(
          new PatchSetApproval.Key(psId, account, labelId),
          (short) 0, TimeUtil.nowTs()));
      update.putReviewer(account, ReviewerState.REVIEWER);
    }
    db.patchSetApprovals().insert(cells);
    return Collections.unmodifiableList(cells);
  }

  public ListMultimap<PatchSet.Id, PatchSetApproval> byChange(ReviewDb db,
      ChangeNotes notes) throws OrmException {
    if (!migration.readPatchSetApprovals()) {
      ImmutableListMultimap.Builder<PatchSet.Id, PatchSetApproval> result =
          ImmutableListMultimap.builder();
      for (PatchSetApproval psa
          : db.patchSetApprovals().byChange(notes.getChangeId())) {
        result.put(psa.getPatchSetId(), psa);
      }
      return result.build();
    }
    return notes.load().getApprovals();
  }

  public List<PatchSetApproval> byPatchSet(ReviewDb db, ChangeNotes notes,
      PatchSet.Id psId) throws OrmException {
    if (!migration.readPatchSetApprovals()) {
      return sortApprovals(db.patchSetApprovals().byPatchSet(psId));
    }
    return notes.load().getApprovals().get(psId);
  }

  public List<PatchSetApproval> byPatchSetUser(ReviewDb db,
      ChangeNotes notes, PatchSet.Id psId, Account.Id accountId)
      throws OrmException {
    if (!migration.readPatchSetApprovals()) {
      return sortApprovals(
          db.patchSetApprovals().byPatchSetUser(psId, accountId));
    }
    return ImmutableList.copyOf(
        filterApprovals(byPatchSet(db, notes, psId), accountId));
  }

  public PatchSetApproval getSubmitter(ReviewDb db, ChangeNotes notes,
      PatchSet.Id c) {
    if (c == null) {
      return null;
    }
    try {
      return getSubmitter(c, byPatchSet(db, notes, c));
    } catch (OrmException e) {
      return null;
    }
  }

  public static PatchSetApproval getSubmitter(PatchSet.Id c,
      Iterable<PatchSetApproval> approvals) {
    if (c == null) {
      return null;
    }
    PatchSetApproval submitter = null;
    for (PatchSetApproval a : approvals) {
      if (a.getPatchSetId().equals(c) && a.getValue() > 0 && a.isSubmit()) {
        if (submitter == null
            || a.getGranted().compareTo(submitter.getGranted()) > 0) {
          submitter = a;
        }
      }
    }
    return submitter;
  }
}
