// Copyright (C) 2015 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.importer;

import com.google.common.base.MoreObjects;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.errors.NoSuchAccountException;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.LabelInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class AddApprovalsStep {

  interface Factory {
    AddApprovalsStep create(Change change, ChangeInfo changeInfo, boolean resume);
  }

  private static final Logger log = LoggerFactory.getLogger(ReplayInlineCommentsStep.class);

  private final AccountUtil accountUtil;
  private final ChangeUpdate.Factory updateFactory;
  private final ReviewDb db;
  private final IdentifiedUser.GenericFactory genericUserFactory;
  private final ChangeData.Factory changeDataFactory;
  private final Change change;
  private final ChangeInfo changeInfo;
  private final boolean resume;

  @Inject
  public AddApprovalsStep(
      AccountUtil accountUtil,
      ChangeUpdate.Factory updateFactory,
      ReviewDb db,
      IdentifiedUser.GenericFactory genericUserFactory,
      ChangeData.Factory changeDataFactory,
      @Assisted Change change,
      @Assisted ChangeInfo changeInfo,
      @Assisted boolean resume) {
    this.accountUtil = accountUtil;
    this.updateFactory = updateFactory;
    this.db = db;
    this.genericUserFactory = genericUserFactory;
    this.changeDataFactory = changeDataFactory;
    this.change = change;
    this.changeInfo = changeInfo;
    this.resume = resume;
  }

  void add(GerritApi api)
      throws OrmException, NoSuchChangeException, IOException, NoSuchAccountException,
          RestApiException, ConfigInvalidException {
    if (resume) {
      db.patchSetApprovals().delete(db.patchSetApprovals().byChange(change.getId()));
    }

    List<PatchSetApproval> approvals = new ArrayList<>();
    for (Entry<String, LabelInfo> e : changeInfo.labels.entrySet()) {
      String labelName = e.getKey();
      LabelInfo label = e.getValue();
      if (label.all != null) {
        for (ApprovalInfo a : label.all) {
          Account.Id user = accountUtil.resolveUser(api, a);
          ChangeData cd = changeDataFactory.create(db, change);
          LabelType labelType = cd.getLabelTypes().byLabel(labelName);
          if (labelType == null) {
            log.warn(
                String.format(
                    "Label '%s' not found in target system."
                        + " This label was referenced by an approval provided from '%s'"
                        + " for change '%s'."
                        + " This approval will be skipped. In order to import this"
                        + " approval configure the missing label and resume the import"
                        + " with the force option.",
                    labelName, a.username, changeInfo.id));
            continue;
          }
          short shortValue = a.value != null ? a.value.shortValue() : 0;
          approvals.add(
              new PatchSetApproval(
                  new PatchSetApproval.Key(
                      change.currentPatchSetId(), user, labelType.getLabelId()),
                  shortValue,
                  MoreObjects.firstNonNull(a.date, TimeUtil.nowTs())));
          ChangeUpdate update = updateFactory.create(cd.notes(), genericUserFactory.create(user));
          if (shortValue != 0) {
            update.putApproval(labelName, shortValue);
          } else {
            update.removeApproval(labelName);
          }
          update.commit();
        }
      }
    }
    db.patchSetApprovals().insert(approvals);
  }
}
