// Copyright (C) 2013 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.hooks.workflow;

import java.io.IOException;

import com.google.gerrit.server.events.AccountAttribute;
import com.google.gerrit.server.events.ApprovalAttribute;
import com.google.gerrit.server.events.ChangeAbandonedEvent;
import com.google.gerrit.server.events.ChangeAttribute;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.ChangeMergedEvent;
import com.google.gerrit.server.events.ChangeRestoredEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;

public class GerritHookFilterAddComment extends GerritHookFilter  {

  @Inject
  private ItsFacade its;

  @Override
  public void doFilter(CommentAddedEvent hook) throws IOException {
    String comment = getComment(hook);
    addComment(hook.change, comment);
  }

  @Override
  public void doFilter(ChangeMergedEvent hook) throws IOException {
    String comment = getComment(hook);
    addComment(hook.change, comment);
  }

  @Override
  public void doFilter(ChangeAbandonedEvent hook) throws IOException {
    String comment = getComment(hook);
    addComment(hook.change, comment);
  }

  @Override
  public void doFilter(ChangeRestoredEvent hook) throws IOException {
    String comment = getComment(hook);
    addComment(hook.change, comment);
  }

  private String getCommentPrefix(ChangeAttribute change) {
    return getChangeIdUrl(change) + " | ";
  }

  private String getComment(ChangeAttribute change, ChangeEvent hook, AccountAttribute who, String what) {
    return getCommentPrefix(change) + "change " + what + " [by " + who + "]";
  }

  private String getComment(ChangeRestoredEvent hook) {
    return getComment(hook.change, hook, hook.restorer, "RESTORED");
  }

  private String getComment(ChangeAbandonedEvent hook) {
    return getComment(hook.change, hook, hook.abandoner, "ABANDONED");
  }

  private String getComment(ChangeMergedEvent hook) {
    return getComment(hook.change, hook, hook.submitter, "APPROVED and MERGED");
  }

  private String getChangeIdUrl(ChangeAttribute change) {
    final String url = change.url;
    String changeId = change.id;
    return its.createLinkForWebui(url, "Gerrit Change " + changeId);
  }

  private String getComment(CommentAddedEvent commentAdded) {
    StringBuilder comment = new StringBuilder(getCommentPrefix(commentAdded.change));

    if (commentAdded.approvals != null && commentAdded.approvals.length > 0) {
      comment.append("Code-Review: ");
      for (ApprovalAttribute approval : commentAdded.approvals) {
        String value = getApprovalValue(approval);
        if (value != null) {
          comment.append(getApprovalType(approval) + ":" + value + " ");
        }
      }
    }

    comment.append(commentAdded.comment + " ");
    comment.append("[by " + commentAdded.author + "]");
    return comment.toString();
  }

  private String getApprovalValue(ApprovalAttribute approval) {
    if (approval.value.equals("0")) {
      return null;
    }

    if (approval.value.charAt(0) != '-') {
      return "+" + approval.value;
    } else {
      return approval.value;
    }
  }

  private String getApprovalType(ApprovalAttribute approval) {
    if (approval.type.equalsIgnoreCase("CRVW")) {
      return "Reviewed";
    } else if (approval.type.equalsIgnoreCase("VRIF")) {
      return "Verified";
    } else
      return approval.type;
  }

  private void addComment(ChangeAttribute change, String comment)
      throws IOException {
    String gitComment = change.subject;;
    String[] issues = getIssueIds(gitComment);

    for (String issue : issues) {
      its.addComment(issue, comment);
    }
  }
}

@@ -688,16 +688,115 @@
 ption;%0A%0A
+import com.google.common.base.Strings;%0Aimport com.google.gerrit.server.config.AnonymousCowardName;%0A
 import c
@@ -1446,16 +1446,86 @@
 e its;%0A%0A
+  @Inject @AnonymousCowardName%0A  private String anonymousCowardName;%0A%0A
   @Overr
@@ -2269,32 +2269,221 @@
 ) + %22 %7C %22;%0A  %7D%0A%0A
+  private String formatAccountAttribute(AccountAttribute who) %7B%0A    if (who != null && !Strings.isNullOrEmpty(who.name)) %7B%0A      return who.name;%0A    %7D%0A    return anonymousCowardName;%0A  %7D%0A%0A
   private String
@@ -2641,14 +2641,46 @@
 by %22
- + 
+%0A        + formatAccountAttribute(
 who
+)
  + %22
@@ -3878,16 +3878,39 @@
 %5Bby %22 + 
+formatAccountAttribute(
 commentA
@@ -3920,16 +3920,17 @@
 d.author
+)
  + %22%5D%22);

Format user names in created bugzilla comments