// Copyright (C) 2008 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.rpc.patch;

import com.google.gerrit.client.data.ApprovalSummary;
import com.google.gerrit.client.data.ApprovalSummarySet;
import com.google.gerrit.client.data.ApprovalType;
import com.google.gerrit.client.data.ApprovalTypes;
import com.google.gerrit.client.data.PatchScript;
import com.google.gerrit.client.data.PatchScriptSettings;
import com.google.gerrit.client.patches.AddReviewerResult;
import com.google.gerrit.client.patches.CommentDetail;
import com.google.gerrit.client.patches.PatchDetailService;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.client.reviewdb.AccountPatchReview;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.client.reviewdb.Change;
import com.google.gerrit.client.reviewdb.ChangeMessage;
import com.google.gerrit.client.reviewdb.Patch;
import com.google.gerrit.client.reviewdb.PatchLineComment;
import com.google.gerrit.client.reviewdb.PatchSet;
import com.google.gerrit.client.reviewdb.PatchSetApproval;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.reviewdb.Patch.Key;
import com.google.gerrit.client.rpc.NoSuchEntityException;
import com.google.gerrit.server.BaseServiceImplementation;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountInfoCacheFactory;
import com.google.gerrit.server.mail.CommentSender;
import com.google.gerrit.server.mail.EmailException;
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.workflow.FunctionState;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtjsonrpc.client.VoidResult;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.OrmRunnable;
import com.google.gwtorm.client.Transaction;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

class PatchDetailServiceImpl extends BaseServiceImplementation implements
    PatchDetailService {
  private final Logger log = LoggerFactory.getLogger(getClass());
  private final CommentSender.Factory commentSenderFactory;
  private final PatchSetInfoFactory patchSetInfoFactory;
  private final ApprovalTypes approvalTypes;

  private final AbandonChange.Factory abandonChangeFactory;
  private final AccountInfoCacheFactory.Factory accountInfoCacheFactory;
  private final AddReviewer.Factory addReviewerFactory;
  private final ChangeControl.Factory changeControlFactory;
  private final CommentDetailFactory.Factory commentDetailFactory;
  private final FunctionState.Factory functionStateFactory;
  private final PatchScriptFactory.Factory patchScriptFactoryFactory;
  private final SaveDraft.Factory saveDraftFactory;

  @Inject
  PatchDetailServiceImpl(final Provider<ReviewDb> schema,
      final Provider<CurrentUser> currentUser,
      final CommentSender.Factory commentSenderFactory,
      final PatchSetInfoFactory patchSetInfoFactory,
      final ApprovalTypes approvalTypes,
      final AbandonChange.Factory abandonChangeFactory,
      final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
      final AddReviewer.Factory addReviewerFactory,
      final ChangeControl.Factory changeControlFactory,
      final CommentDetailFactory.Factory commentDetailFactory,
      final FunctionState.Factory functionStateFactory,
      final PatchScriptFactory.Factory patchScriptFactoryFactory,
      final SaveDraft.Factory saveDraftFactory) {
    super(schema, currentUser);
    this.patchSetInfoFactory = patchSetInfoFactory;
    this.commentSenderFactory = commentSenderFactory;
    this.approvalTypes = approvalTypes;

    this.abandonChangeFactory = abandonChangeFactory;
    this.accountInfoCacheFactory = accountInfoCacheFactory;
    this.addReviewerFactory = addReviewerFactory;
    this.changeControlFactory = changeControlFactory;
    this.commentDetailFactory = commentDetailFactory;
    this.functionStateFactory = functionStateFactory;
    this.patchScriptFactoryFactory = patchScriptFactoryFactory;
    this.saveDraftFactory = saveDraftFactory;
  }

  public void patchScript(final Patch.Key patchKey, final PatchSet.Id psa,
      final PatchSet.Id psb, final PatchScriptSettings s,
      final AsyncCallback<PatchScript> callback) {
    if (psb == null) {
      callback.onFailure(new NoSuchEntityException());
      return;
    }
    patchScriptFactoryFactory.create(patchKey, psa, psb, s).to(callback);
  }

  public void patchComments(final Patch.Key patchKey, final PatchSet.Id psa,
      final PatchSet.Id psb, final AsyncCallback<CommentDetail> callback) {
    if (psb == null) {
      callback.onFailure(new NoSuchEntityException());
      return;
    }
    commentDetailFactory.create(patchKey, psa, psb).to(callback);
  }

  public void saveDraft(final PatchLineComment comment,
      final AsyncCallback<PatchLineComment> callback) {
    saveDraftFactory.create(comment).to(callback);
  }

  public void deleteDraft(final PatchLineComment.Key commentKey,
      final AsyncCallback<VoidResult> callback) {
    run(callback, new Action<VoidResult>() {
      public VoidResult run(ReviewDb db) throws OrmException, Failure {
        final PatchLineComment comment = db.patchComments().get(commentKey);
        if (comment == null) {
          throw new Failure(new NoSuchEntityException());
        }
        if (!getAccountId().equals(comment.getAuthor())) {
          throw new Failure(new NoSuchEntityException());
        }
        if (comment.getStatus() != PatchLineComment.Status.DRAFT) {
          throw new Failure(new IllegalStateException("Comment published"));
        }
        db.patchComments().delete(Collections.singleton(comment));
        return VoidResult.INSTANCE;
      }
    });
  }

  public void publishComments(final PatchSet.Id psid, final String message,
      final Set<ApprovalCategoryValue.Id> approvals,
      final AsyncCallback<VoidResult> callback) {
    run(callback, new Action<VoidResult>() {
      public VoidResult run(ReviewDb db) throws OrmException, Failure {
        final PublishResult r;

        r = db.run(new OrmRunnable<PublishResult, ReviewDb>() {
          public PublishResult run(ReviewDb db, Transaction txn, boolean retry)
              throws OrmException {
            return doPublishComments(psid, message, approvals, db, txn);
          }
        });

        try {
          final CommentSender cm;
          cm = commentSenderFactory.create(r.change);
          cm.setFrom(getAccountId());
          cm.setPatchSet(r.patchSet, patchSetInfoFactory.get(psid));
          cm.setChangeMessage(r.message);
          cm.setPatchLineComments(r.comments);
          cm.setReviewDb(db);
          cm.send();
        } catch (EmailException e) {
          log.error("Cannot send comments by email for patch set " + psid, e);
          throw new Failure(e);
        } catch (PatchSetInfoNotAvailableException e) {
          log.error("Failed to obtain PatchSetInfo for patch set " + psid, e);
          throw new Failure(e);
        }
        return VoidResult.INSTANCE;
      }
    });
  }

  /**
   * Update the reviewed status for the file by user @code{account}
   */
  public void setReviewedByCurrentUser(final Key patchKey,
      final boolean reviewed, AsyncCallback<VoidResult> callback) {
    run(callback, new Action<VoidResult>() {
      public VoidResult run(ReviewDb db) throws OrmException {
        Account.Id account = getAccountId();
        AccountPatchReview.Key key =
            new AccountPatchReview.Key(patchKey, account);
        AccountPatchReview apr = db.accountPatchReviews().get(key);
        if (apr == null && reviewed) {
          db.accountPatchReviews().insert(
              Collections.singleton(new AccountPatchReview(patchKey, account)));
        } else if (apr != null && !reviewed) {
          db.accountPatchReviews().delete(Collections.singleton(apr));
        }
        return VoidResult.INSTANCE;
      }
    });
  }


  private static class PublishResult {
    Change change;
    PatchSet patchSet;
    ChangeMessage message;
    List<PatchLineComment> comments;
  }

  private PublishResult doPublishComments(final PatchSet.Id psid,
      final String messageText, final Set<ApprovalCategoryValue.Id> approvals,
      final ReviewDb db, final Transaction txn) throws OrmException {
    final PublishResult r = new PublishResult();
    final Account.Id me = getAccountId();
    r.change = db.changes().get(psid.getParentKey());
    r.patchSet = db.patchSets().get(psid);
    if (r.change == null || r.patchSet == null) {
      throw new OrmException(new NoSuchEntityException());
    }

    final boolean iscurrent = psid.equals(r.change.currentPatchSetId());
    r.comments = db.patchComments().draft(psid, me).toList();
    for (final PatchLineComment c : r.comments) {
      c.setStatus(PatchLineComment.Status.PUBLISHED);
      c.updated();
    }
    db.patchComments().update(r.comments, txn);

    final StringBuilder msgbuf = new StringBuilder();
    final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> values =
        new HashMap<ApprovalCategory.Id, ApprovalCategoryValue.Id>();
    for (final ApprovalCategoryValue.Id v : approvals) {
      values.put(v.getParentKey(), v);
    }

    final boolean applyApprovals = iscurrent && r.change.getStatus().isOpen();
    final Map<ApprovalCategory.Id, PatchSetApproval> have =
        new HashMap<ApprovalCategory.Id, PatchSetApproval>();
    for (PatchSetApproval a : db.patchSetApprovals().byPatchSetUser(psid, me)) {
      have.put(a.getCategoryId(), a);
    }
    for (final ApprovalType at : approvalTypes.getApprovalTypes()) {
      final ApprovalCategoryValue.Id v = values.get(at.getCategory().getId());
      if (v == null) {
        continue;
      }

      final ApprovalCategoryValue val = at.getValue(v.get());
      if (val == null) {
        continue;
      }

      PatchSetApproval mycatpp = have.remove(v.getParentKey());
      if (mycatpp == null) {
        if (msgbuf.length() > 0) {
          msgbuf.append("; ");
        }
        msgbuf.append(val.getName());
        if (applyApprovals) {
          mycatpp =
              new PatchSetApproval(new PatchSetApproval.Key(psid, me, v
                  .getParentKey()), v.get());
          db.patchSetApprovals().insert(Collections.singleton(mycatpp), txn);
        }

      } else if (mycatpp.getValue() != v.get()) {
        if (msgbuf.length() > 0) {
          msgbuf.append("; ");
        }
        msgbuf.append(val.getName());
        if (applyApprovals) {
          mycatpp.setValue(v.get());
          mycatpp.setGranted();
          db.patchSetApprovals().update(Collections.singleton(mycatpp), txn);
        }
      }
    }
    if (applyApprovals) {
      db.patchSetApprovals().delete(have.values(), txn);
    }

    if (msgbuf.length() > 0) {
      msgbuf.insert(0, "Patch Set " + psid.get() + ": ");
      msgbuf.append("\n\n");
    } else if (!iscurrent) {
      msgbuf.append("Patch Set " + psid.get() + ":\n\n");
    }
    if (messageText != null) {
      msgbuf.append(messageText);
    }
    if (msgbuf.length() > 0) {
      r.message =
          new ChangeMessage(new ChangeMessage.Key(r.change.getId(), ChangeUtil
              .messageUUID(db)), me);
      r.message.setMessage(msgbuf.toString());
      db.changeMessages().insert(Collections.singleton(r.message), txn);
    }

    ChangeUtil.updated(r.change);
    db.changes().update(Collections.singleton(r.change), txn);
    return r;
  }

  public void addReviewers(final Change.Id id, final List<String> reviewers,
      final AsyncCallback<AddReviewerResult> callback) {
    addReviewerFactory.create(id, reviewers).to(callback);
  }

  public void abandonChange(final PatchSet.Id patchSetId, final String message,
      final AsyncCallback<VoidResult> callback) {
    abandonChangeFactory.create(patchSetId, message).to(callback);
  }

  public void userApprovals(final Set<Change.Id> cids, final Account.Id aid,
      final AsyncCallback<ApprovalSummarySet> callback) {
    run(callback, new Action<ApprovalSummarySet>() {
      public ApprovalSummarySet run(ReviewDb db)
        throws OrmException {
        final Map<Change.Id, ApprovalSummary> approvals =
            new HashMap<Change.Id, ApprovalSummary>();
        final AccountInfoCacheFactory aicFactory =
            accountInfoCacheFactory.create();

        aicFactory.want(aid);
        for (final Change.Id id : cids) {
          try {
            final ChangeControl cc = changeControlFactory.validateFor(id);
            final Change change = cc.getChange();
            final PatchSet.Id ps_id = change.currentPatchSetId();
            final Map<ApprovalCategory.Id, PatchSetApproval> psas =
                new HashMap<ApprovalCategory.Id, PatchSetApproval>();
            final FunctionState fs =
                functionStateFactory.create(change, ps_id, psas.values());

            for (final PatchSetApproval ca : db.patchSetApprovals()
                .byPatchSetUser(ps_id, aid)) {
              final ApprovalCategory.Id category = ca.getCategoryId();
              if (change.getStatus().isOpen()) {
                fs.normalize(approvalTypes.getApprovalType(category), ca);
              }
              if (ca.getValue() == 0
                  || ApprovalCategory.SUBMIT.equals(category)) {
                continue;
              }
              psas.put(category, ca);
            }

            approvals.put(id, new ApprovalSummary(psas.values()));
          } catch (NoSuchChangeException nsce) {
            /* The user has no access to see this change, so we
             * simply do not provide any details about it.
             */
          }
        }
        return new ApprovalSummarySet(aicFactory.create(), approvals);
      }
    });
  }

  public void strongestApprovals(final Set<Change.Id> cids,
      final AsyncCallback<ApprovalSummarySet> callback) {
    run(callback, new Action<ApprovalSummarySet>() {
      public ApprovalSummarySet run(ReviewDb db)
          throws OrmException {
        final Map<Change.Id, ApprovalSummary> approvals =
            new HashMap<Change.Id, ApprovalSummary>();
        final AccountInfoCacheFactory aicFactory =
            accountInfoCacheFactory.create();

        for (final Change.Id id : cids) {
          try {
            final ChangeControl cc = changeControlFactory.validateFor(id);
            final Change change = cc.getChange();
            final PatchSet.Id ps_id = change.currentPatchSetId();
            final Map<ApprovalCategory.Id, PatchSetApproval> psas =
                new HashMap<ApprovalCategory.Id, PatchSetApproval>();
            final FunctionState fs =
                functionStateFactory.create(change, ps_id, psas.values());

            for (PatchSetApproval ca : db.patchSetApprovals()
                .byPatchSet(ps_id)) {
              final ApprovalCategory.Id category = ca.getCategoryId();
              if (change.getStatus().isOpen()) {
                fs.normalize(approvalTypes.getApprovalType(category), ca);
              }
              if (ca.getValue() == 0
                  || ApprovalCategory.SUBMIT.equals(category)) {
                continue;
              }
              boolean keep = true;
              if (psas.containsKey(category)) {
                final short oldValue = psas.get(category).getValue();
                final short newValue = ca.getValue();
                keep = (Math.abs(oldValue) < Math.abs(newValue))
                    || ((Math.abs(oldValue) == Math.abs(newValue)
                        && (newValue < oldValue)));
              }
              if (keep) {
                aicFactory.want(ca.getAccountId());
                psas.put(category, ca);
              }
            }

            approvals.put(id, new ApprovalSummary(psas.values()));
          } catch (NoSuchChangeException nsce) {
            /* The user has no access to see this change, so we
             * simply do not provide any details about it.
             */
          }
        }

        return new ApprovalSummarySet(aicFactory.create(), approvals);
      }
    });
  }
}
