// 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.patch;

import com.google.gerrit.common.ChangeHookRunner;
import com.google.gerrit.common.data.ApprovalType;
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.ChangeMessage;
import com.google.gerrit.reviewdb.PatchLineComment;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.PatchSetApproval;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.mail.CommentSender;
import com.google.gerrit.server.mail.EmailException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.workflow.FunctionState;
import com.google.gwtjsonrpc.client.VoidResult;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

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

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;
import java.util.concurrent.Callable;

public class PublishComments implements Callable<VoidResult> {
  private static final Logger log =
      LoggerFactory.getLogger(PublishComments.class);

  public interface Factory {
    PublishComments create(PatchSet.Id patchSetId, String messageText,
        Set<ApprovalCategoryValue.Id> approvals);
  }

  private final ReviewDb db;
  private final IdentifiedUser user;
  private final ApprovalTypes types;
  private final CommentSender.Factory commentSenderFactory;
  private final PatchSetInfoFactory patchSetInfoFactory;
  private final ChangeControl.Factory changeControlFactory;
  private final FunctionState.Factory functionStateFactory;
  private final ChangeHookRunner hooks;

  private final PatchSet.Id patchSetId;
  private final String messageText;
  private final Set<ApprovalCategoryValue.Id> approvals;

  private Change change;
  private PatchSet patchSet;
  private ChangeMessage message;
  private List<PatchLineComment> drafts;

  @Inject
  PublishComments(final ReviewDb db, final IdentifiedUser user,
      final ApprovalTypes approvalTypes,
      final CommentSender.Factory commentSenderFactory,
      final PatchSetInfoFactory patchSetInfoFactory,
      final ChangeControl.Factory changeControlFactory,
      final FunctionState.Factory functionStateFactory,
      final ChangeHookRunner hooks,

      @Assisted final PatchSet.Id patchSetId,
      @Assisted final String messageText,
      @Assisted final Set<ApprovalCategoryValue.Id> approvals) {
    this.db = db;
    this.user = user;
    this.types = approvalTypes;
    this.patchSetInfoFactory = patchSetInfoFactory;
    this.commentSenderFactory = commentSenderFactory;
    this.changeControlFactory = changeControlFactory;
    this.functionStateFactory = functionStateFactory;
    this.hooks = hooks;

    this.patchSetId = patchSetId;
    this.messageText = messageText;
    this.approvals = approvals;
  }

  @Override
  public VoidResult call() throws NoSuchChangeException, OrmException {
    final Change.Id changeId = patchSetId.getParentKey();
    final ChangeControl ctl = changeControlFactory.validateFor(changeId);
    change = ctl.getChange();
    patchSet = db.patchSets().get(patchSetId);
    if (patchSet == null) {
      throw new NoSuchChangeException(changeId);
    }
    drafts = drafts();

    publishDrafts();

    final boolean isCurrent = patchSetId.equals(change.currentPatchSetId());
    if (isCurrent && change.getStatus().isOpen()) {
      publishApprovals();
    } else {
      publishMessageOnly();
    }

    touchChange();
    email();
    fireHook();
    return VoidResult.INSTANCE;
  }

  private void publishDrafts() throws OrmException {
    for (final PatchLineComment c : drafts) {
      c.setStatus(PatchLineComment.Status.PUBLISHED);
      c.updated();
    }
    db.patchComments().update(drafts);
  }

  private void publishApprovals() throws OrmException {
    ChangeUtil.updated(change);

    final Set<ApprovalCategory.Id> dirty = new HashSet<ApprovalCategory.Id>();
    final List<PatchSetApproval> ins = new ArrayList<PatchSetApproval>();
    final List<PatchSetApproval> upd = new ArrayList<PatchSetApproval>();
    final Collection<PatchSetApproval> all =
        db.patchSetApprovals().byPatchSet(patchSetId).toList();
    final Map<ApprovalCategory.Id, PatchSetApproval> mine = mine(all);

    // Ensure any new approvals are stored properly.
    //
    for (final ApprovalCategoryValue.Id want : approvals) {
      PatchSetApproval a = mine.get(want.getParentKey());
      if (a == null) {
        a = new PatchSetApproval(new PatchSetApproval.Key(//
            patchSetId, user.getAccountId(), want.getParentKey()), want.get());
        a.cache(change);
        ins.add(a);
        all.add(a);
        mine.put(a.getCategoryId(), a);
        dirty.add(a.getCategoryId());
      }
    }

    // Normalize all of the items the user is changing.
    //
    final FunctionState functionState =
        functionStateFactory.create(change, patchSetId, all);
    for (final ApprovalCategoryValue.Id want : approvals) {
      final PatchSetApproval a = mine.get(want.getParentKey());
      final short o = a.getValue();
      a.setValue(want.get());
      a.cache(change);
      functionState.normalize(types.getApprovalType(a.getCategoryId()), a);
      if (o != a.getValue()) {
        // Value changed, ensure we update the database.
        //
        a.setGranted();
        dirty.add(a.getCategoryId());
      }
      if (!ins.contains(a)) {
        upd.add(a);
      }
    }

    // Format a message explaining the actions taken.
    //
    final StringBuilder msgbuf = new StringBuilder();
    for (final ApprovalType at : types.getApprovalTypes()) {
      if (dirty.contains(at.getCategory().getId())) {
        final PatchSetApproval a = mine.get(at.getCategory().getId());
        if (a.getValue() == 0 && ins.contains(a)) {
          // Don't say "no score" for an initial entry.
          continue;
        }

        final ApprovalCategoryValue val = at.getValue(a);
        if (msgbuf.length() > 0) {
          msgbuf.append("; ");
        }
        if (val != null && val.getName() != null && !val.getName().isEmpty()) {
          msgbuf.append(val.getName());
        } else {
          msgbuf.append(at.getCategory().getName());
          msgbuf.append(" ");
          if (a.getValue() > 0) msgbuf.append('+');
          msgbuf.append(a.getValue());
        }
      }
    }

    // Update dashboards for everyone else.
    //
    for (PatchSetApproval a : all) {
      if (!user.getAccountId().equals(a.getAccountId())) {
        a.cache(change);
        upd.add(a);
      }
    }

    db.patchSetApprovals().update(upd);
    db.patchSetApprovals().insert(ins);

    summarizeInlineComments(msgbuf);
    message(msgbuf.toString());
  }

  private void publishMessageOnly() throws OrmException {
    StringBuilder msgbuf = new StringBuilder();
    summarizeInlineComments(msgbuf);
    message(msgbuf.toString());
  }

  private void message(String actions) throws OrmException {
    if ((actions == null || actions.isEmpty())
        && (messageText == null || messageText.isEmpty())) {
      // They had nothing to say?
      //
      return;
    }

    final StringBuilder msgbuf = new StringBuilder();
    msgbuf.append("Patch Set " + patchSetId.get() + ":");
    if (actions != null && !actions.isEmpty()) {
      msgbuf.append(" ");
      msgbuf.append(actions);
    }
    msgbuf.append("\n\n");
    msgbuf.append(messageText != null ? messageText : "");

    message = new ChangeMessage(new ChangeMessage.Key(change.getId(),//
        ChangeUtil.messageUUID(db)), user.getAccountId());
    message.setMessage(msgbuf.toString());
    db.changeMessages().insert(Collections.singleton(message));
  }

  private Map<ApprovalCategory.Id, PatchSetApproval> mine(
      Collection<PatchSetApproval> all) {
    Map<ApprovalCategory.Id, PatchSetApproval> r =
        new HashMap<ApprovalCategory.Id, PatchSetApproval>();
    for (PatchSetApproval a : all) {
      if (user.getAccountId().equals(a.getAccountId())) {
        r.put(a.getCategoryId(), a);
      }
    }
    return r;
  }

  private void touchChange() {
    try {
      ChangeUtil.touch(change, db);
    } catch (OrmException e) {
    }
  }

  private List<PatchLineComment> drafts() throws OrmException {
    return db.patchComments().draft(patchSetId, user.getAccountId()).toList();
  }

  private void email() {
    try {
      final CommentSender cm = commentSenderFactory.create(change);
      cm.setFrom(user.getAccountId());
      cm.setPatchSet(patchSet, patchSetInfoFactory.get(patchSetId));
      cm.setChangeMessage(message);
      cm.setPatchLineComments(drafts);
      cm.send();
    } catch (EmailException e) {
      log.error("Cannot send comments by email for patch set " + patchSetId, e);
    } catch (PatchSetInfoNotAvailableException e) {
      log.error("Failed to obtain PatchSetInfo for patch set " + patchSetId, e);
    }
  }

  private void fireHook() {
    final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> changed =
        new HashMap<ApprovalCategory.Id, ApprovalCategoryValue.Id>();
    for (ApprovalCategoryValue.Id v : approvals) {
      changed.put(v.getParentKey(), v);
    }

    hooks.doCommentAddedHook(change, user.getAccount(), patchSet, messageText, changed);
  }

  private void summarizeInlineComments(StringBuilder in) {
    if (!drafts.isEmpty()) {
      if (in.length() != 0) {
        in.append("\n\n");
      }
      if (drafts.size() == 1) {
        in.append("(1 inline comment)");
      } else {
        in.append("(" + drafts.size() + " inline comments)");
      }
    }
  }
}
