// 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.httpd.rpc.changedetail;

import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.common.data.PatchSetPublishDetail;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.PatchSetApproval;
import com.google.gerrit.reviewdb.PatchSetInfo;
import com.google.gerrit.reviewdb.RefRight;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RefControl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

final class PatchSetPublishDetailFactory extends Handler<PatchSetPublishDetail> {
  interface Factory {
    PatchSetPublishDetailFactory create(PatchSet.Id patchSetId);
  }

  private final ProjectCache projectCache;
  private final PatchSetInfoFactory infoFactory;
  private final ApprovalTypes approvalTypes;
  private final ReviewDb db;
  private final ChangeControl.Factory changeControlFactory;
  private final AccountInfoCacheFactory aic;
  private final IdentifiedUser user;

  private final PatchSet.Id patchSetId;

  private AccountInfoCache accounts;
  private PatchSetInfo patchSetInfo;
  private Change change;
  private List<PatchLineComment> drafts;
  private Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> allowed;
  private Map<ApprovalCategory.Id, PatchSetApproval> given;

  @Inject
  PatchSetPublishDetailFactory(final PatchSetInfoFactory infoFactory,
      final ProjectCache projectCache, final ApprovalTypes approvalTypes,
      final ReviewDb db,
      final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
      final ChangeControl.Factory changeControlFactory,
      final IdentifiedUser user, @Assisted final PatchSet.Id patchSetId) {
    this.projectCache = projectCache;
    this.infoFactory = infoFactory;
    this.approvalTypes = approvalTypes;
    this.db = db;
    this.changeControlFactory = changeControlFactory;
    this.aic = accountInfoCacheFactory.create();
    this.user = user;

    this.patchSetId = patchSetId;
  }

  @Override
  public PatchSetPublishDetail call() throws OrmException,
      PatchSetInfoNotAvailableException, NoSuchChangeException {
    final Change.Id changeId = patchSetId.getParentKey();
    final ChangeControl control = changeControlFactory.validateFor(changeId);
    change = control.getChange();
    patchSetInfo = infoFactory.get(patchSetId);
    drafts = db.patchComments().draft(patchSetId, user.getAccountId()).toList();

    allowed = new HashMap<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>>();
    given = new HashMap<ApprovalCategory.Id, PatchSetApproval>();
    if (change.getStatus().isOpen()
        && patchSetId.equals(change.currentPatchSetId())) {
      computeAllowed();
      for (final PatchSetApproval a : db.patchSetApprovals().byPatchSetUser(
          patchSetId, user.getAccountId())) {
        given.put(a.getCategoryId(), a);
      }
    }

    aic.want(change.getOwner());
    accounts = aic.create();

    PatchSetPublishDetail detail = new PatchSetPublishDetail();
    detail.setAccounts(accounts);
    detail.setPatchSetInfo(patchSetInfo);
    detail.setChange(change);
    detail.setDrafts(drafts);
    detail.setAllowed(allowed);
    detail.setGiven(given);

    return detail;
  }

  private void computeAllowed() {
    final Set<AccountGroup.Id> am = user.getEffectiveGroups();
    final ProjectState pe = projectCache.get(change.getProject());
    for (ApprovalCategory.Id category : approvalTypes.getApprovalCategories()) {
      List<RefRight> categoryRights = new ArrayList<RefRight>();
      categoryRights.addAll(filterMatching(pe.getLocalRights(category)));
      categoryRights.addAll(filterMatching(pe.getInheritedRights(category)));
      Collections.sort(categoryRights, RefRight.REF_PATTERN_ORDER);

      computeAllowed(am, categoryRights, category);
    }
  }

  private List<RefRight> filterMatching(Collection<RefRight> rights) {
    List<RefRight> result = new ArrayList<RefRight>();
    for (RefRight right : rights) {
      if (RefControl.matches(change.getDest().get(), right.getRefPattern())) {
        result.add(right);
      }
    }
    return result;
  }

  private void computeAllowed(final Set<AccountGroup.Id> am,
      final List<RefRight> list, ApprovalCategory.Id category) {

    Set<ApprovalCategoryValue.Id> s = allowed.get(category);
    if (s == null) {
      s = new HashSet<ApprovalCategoryValue.Id>();
      allowed.put(category, s);
    }

    boolean foundExclusive = false;
    String previousPattern = "";
    for (final RefRight r : list) {

      if (!am.contains(r.getAccountGroupId())) {
        if (r.isExclusive()) {
          foundExclusive = true;
        }
        continue;
      }

      if (foundExclusive && !previousPattern.equals(r.getRefPattern())) {
        break;
      }

      if (r.isExclusive()) {
        foundExclusive = true;
      }

      previousPattern = r.getRefPattern();

      final ApprovalType at =
          approvalTypes.getApprovalType(r.getApprovalCategoryId());
      for (short m = r.getMinValue(); m <= r.getMaxValue(); m++) {
        final ApprovalCategoryValue v = at.getValue(m);
        if (v != null) {
          s.add(v.getId());
        }
      }
    }
  }
}
