// Copyright (C) 2016 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.mail;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.gerrit.entities.Comment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/** Provides parsing functionality for plaintext email. */
public class TextParser {
  private TextParser() {}

  /**
   * Parses comments from plaintext email.
   *
   * @param email @param email the message as received from the email service
   * @param comments list of {@link Comment}s previously persisted on the change that caused the
   *     original notification email to be sent out. Ordering must be the same as in the outbound
   *     email
   * @param changeUrl canonical change url that points to the change on this Gerrit instance.
   *     Example: https://go-review.googlesource.com/#/c/91570
   * @return list of MailComments parsed from the plaintext part of the email
   */
  public static List<MailComment> parse(
      MailMessage email, Collection<Comment> comments, String changeUrl) {
    String body = email.textContent();
    // Replace CR-LF by \n
    body = body.replace("\r\n", "\n");

    List<MailComment> parsedComments = new ArrayList<>();

    // Some email clients (like GMail) use >> for enquoting text when there are
    // inline comments that the users typed. These will then be enquoted by a
    // single >. We sanitize this by unifying it into >. Inline comments typed
    // by the user will not be enquoted.
    //
    // Example:
    // Some comment
    // >> Quoted Text
    // >> Quoted Text
    // > A comment typed in the email directly
    String singleQuotePattern = "\n> ";
    String doubleQuotePattern = "\n>> ";
    if (countOccurrences(body, doubleQuotePattern) > countOccurrences(body, singleQuotePattern)) {
      body = body.replace(doubleQuotePattern, singleQuotePattern);
    }

    PeekingIterator<Comment> iter = Iterators.peekingIterator(comments.iterator());

    MailComment currentComment = null;
    String lastEncounteredFileName = null;
    Comment lastEncounteredComment = null;
    for (String line : Splitter.on('\n').split(body)) {
      if (line.equals(">")) {
        // Skip empty lines
        continue;
      }
      if (line.startsWith("> ")) {
        line = line.substring("> ".length()).trim();
        // This is not a comment, try to advance the file/comment pointers and
        // add previous comment to list if applicable
        if (currentComment != null) {
          if (currentComment.type == MailComment.CommentType.CHANGE_MESSAGE) {
            currentComment.message = ParserUtil.trimQuotation(currentComment.message);
          }
          if (!Strings.isNullOrEmpty(currentComment.message)) {
            ParserUtil.appendOrAddNewComment(currentComment, parsedComments);
          }
          currentComment = null;
        }

        if (!iter.hasNext()) {
          continue;
        }
        Comment perspectiveComment = iter.peek();
        if (line.equals(ParserUtil.filePath(changeUrl, perspectiveComment))) {
          if (lastEncounteredFileName == null
              || !lastEncounteredFileName.equals(perspectiveComment.key.filename)) {
            // This is the annotation of a file
            lastEncounteredFileName = perspectiveComment.key.filename;
            lastEncounteredComment = null;
          } else if (perspectiveComment.lineNbr == 0) {
            // This was originally a file-level comment
            lastEncounteredComment = perspectiveComment;
            iter.next();
          }
        } else if (ParserUtil.isCommentUrl(line, changeUrl, perspectiveComment)) {
          lastEncounteredComment = perspectiveComment;
          iter.next();
        }
      } else {
        // This is a comment. Try to append to previous comment if applicable or
        // create a new comment.
        if (currentComment == null) {
          // Start new comment
          currentComment = new MailComment();
          currentComment.message = line;
          if (lastEncounteredComment == null) {
            if (lastEncounteredFileName == null) {
              // Change message
              currentComment.type = MailComment.CommentType.CHANGE_MESSAGE;
            } else {
              // File comment not sent in reply to another comment
              currentComment.type = MailComment.CommentType.FILE_COMMENT;
              currentComment.fileName = lastEncounteredFileName;
            }
          } else {
            // Comment sent in reply to another comment
            currentComment.inReplyTo = lastEncounteredComment;
            currentComment.type = MailComment.CommentType.INLINE_COMMENT;
          }
        } else {
          // Attach to previous comment
          currentComment.message += "\n" + line;
        }
      }
    }
    // There is no need to attach the currentComment after this loop as all
    // emails have footers and other enquoted text after the last comment
    // appeared and the last comment will have already been added to the list
    // at this point.

    return parsedComments;
  }

  /** Counts the occurrences of pattern in s */
  private static int countOccurrences(String s, String pattern) {
    return (s.length() - s.replace(pattern, "").length()) / pattern.length();
  }
}
