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

import com.google.common.base.Strings;
import com.google.common.collect.Ordering;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.ReviewInput.NotifyHandling;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.patch.PatchFile;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.client.KeyUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/** Send comments, after the author of them hit used Publish Comments in the UI. */
public class CommentSender extends ReplyToChangeSender {
  private static final Logger log = LoggerFactory
      .getLogger(CommentSender.class);

  public static interface Factory {
    public CommentSender create(NotifyHandling notify, Change change);
  }

  private final NotifyHandling notify;
  private List<PatchLineComment> inlineComments = Collections.emptyList();

  @Inject
  public CommentSender(EmailArguments ea,
      @Assisted NotifyHandling notify,
      @Assisted Change c) {
    super(ea, c, "comment");
    this.notify = notify;
  }

  public void setPatchLineComments(final List<PatchLineComment> plc) {
    inlineComments = plc;

    Set<String> paths = new HashSet<String>();
    for (PatchLineComment c : plc) {
      Patch.Key p = c.getKey().getParentKey();
      if (!Patch.COMMIT_MSG.equals(p.getFileName())) {
        paths.add(p.getFileName());
      }
    }
    changeData.setCurrentFilePaths(Ordering.natural().sortedCopy(paths));
  }

  @Override
  protected void init() throws EmailException {
    super.init();

    if (notify.compareTo(NotifyHandling.OWNER_REVIEWERS) >= 0) {
      ccAllApprovals();
    }
    if (notify.compareTo(NotifyHandling.ALL) >= 0) {
      bccStarredBy();
      includeWatchers(NotifyType.ALL_COMMENTS);
    }
  }

  @Override
  public void formatChange() throws EmailException {
    appendText(velocifyFile("Comment.vm"));
  }

  @Override
  public void formatFooter() throws EmailException {
    appendText(velocifyFile("CommentFooter.vm"));
  }

  public boolean hasInlineComments() {
    return !inlineComments.isEmpty();
  }

  public String getInlineComments() {
    return getInlineComments(1);
  }

  public String getInlineComments(int lines) {
    StringBuilder cmts = new StringBuilder();
    final Repository repo = getRepository();
    try {
      PatchList patchList = null;
      if (repo != null) {
        try {
          patchList = getPatchList();
        } catch (PatchListNotAvailableException e) {
          patchList = null;
        }
      }

      Patch.Key currentFileKey = null;
      PatchFile currentFileData = null;
      for (final PatchLineComment c : inlineComments) {
        final Patch.Key pk = c.getKey().getParentKey();

        if (!pk.equals(currentFileKey)) {
          String link = makeLink(pk);
          if (link != null) {
            cmts.append(link).append('\n');
          }
          if (Patch.COMMIT_MSG.equals(pk.get())) {
            cmts.append("Commit Message:\n\n");
          } else {
            cmts.append("File ").append(pk.get()).append(":\n\n");
          }
          currentFileKey = pk;

          if (patchList != null) {
            try {
              currentFileData =
                  new PatchFile(repo, patchList, pk.get());
            } catch (IOException e) {
              log.warn(String.format(
                  "Cannot load %s from %s in %s",
                  pk.getFileName(),
                  patchList.getNewId().name(),
                  projectState.getProject().getName()), e);
              currentFileData = null;
            }
          }
        }

        if (currentFileData != null) {
          appendComment(cmts, lines, currentFileData, c);
        }
        cmts.append("\n\n");
      }
    } finally {
      if (repo != null) {
        repo.close();
      }
    }
    return cmts.toString();
  }

  private void appendComment(StringBuilder out, int contextLines,
      PatchFile currentFileData, PatchLineComment comment) {
    short side = comment.getSide();
    CommentRange range = comment.getRange();
    if (range != null) {
      String prefix = String.format("Line %d: ", range.getStartLine());
      for (int n = range.getStartLine(); n <= range.getEndLine(); n++) {
        out.append(n == range.getStartLine()
            ? prefix
            : Strings.padStart(": ", prefix.length(), ' '));
        try {
          String s = currentFileData.getLine(side, n);
          if (n == range.getStartLine() && n == range.getEndLine()) {
            s = s.substring(
                Math.min(range.getStartCharacter(), s.length()),
                Math.min(range.getEndCharacter(), s.length()));
          } else if (n == range.getStartLine()) {
            s = s.substring(Math.min(range.getStartCharacter(), s.length()));
          } else if (n == range.getEndLine()) {
            s = s.substring(0, Math.min(range.getEndCharacter(), s.length()));
          }
          out.append(s);
        } catch (Throwable e) {
          // Don't quote the line if we can't safely convert it.
        }
        out.append('\n');
      }
      appendQuotedParent(out, comment);
      out.append(comment.getMessage().trim()).append('\n');
    } else {
      int lineNbr = comment.getLine();
      int maxLines;
      try {
        maxLines = currentFileData.getLineCount(side);
      } catch (Throwable e) {
        maxLines = lineNbr;
      }

      final int startLine = Math.max(1, lineNbr - contextLines + 1);
      final int stopLine = Math.min(maxLines, lineNbr + contextLines);

      for (int line = startLine; line <= lineNbr; ++line) {
        appendFileLine(out, currentFileData, side, line);
      }
      appendQuotedParent(out, comment);
      out.append(comment.getMessage().trim()).append('\n');

      for (int line = lineNbr + 1; line < stopLine; ++line) {
        appendFileLine(out, currentFileData, side, line);
      }
    }
  }

  private void appendFileLine(StringBuilder cmts, PatchFile fileData, short side, int line) {
    cmts.append("Line " + line);
    try {
      final String lineStr = fileData.getLine(side, line);
      cmts.append(": ");
      cmts.append(lineStr);
    } catch (Throwable e) {
      // Don't quote the line if we can't safely convert it.
    }
    cmts.append("\n");
  }

  private void appendQuotedParent(StringBuilder out, PatchLineComment child) {
    if (child.getParentUuid() != null) {
      PatchLineComment parent;
      try {
        parent = args.db.get().patchComments().get(
            new PatchLineComment.Key(
                child.getKey().getParentKey(),
                child.getParentUuid()));
      } catch (OrmException e) {
        parent = null;
      }
      if (parent != null) {
        String msg = parent.getMessage().trim();
        if (msg.length() > 75) {
          msg = msg.substring(0, 75);
        }
        int lf = msg.indexOf('\n');
        if (lf > 0) {
          msg = msg.substring(0, lf);
        }
        out.append("> ").append(msg).append('\n');
      }
    }
  }

  // Makes a link back to the given patch set and file.
  private String makeLink(Patch.Key patch) {
    String url = getGerritUrl();
    if (url == null) {
      return null;
    }

    PatchSet.Id ps = patch.getParentKey();
    Change.Id c = ps.getParentKey();
    return new StringBuilder()
      .append(url)
      .append("#/c/").append(c)
      .append('/').append(ps.get())
      .append('/').append(KeyUtil.encode(patch.get()))
      .toString();
  }

  private Repository getRepository() {
    try {
      return args.server.openRepository(projectState.getProject().getNameKey());
    } catch (IOException e) {
      return null;
    }
  }
}
