// Copyright (C) 2019 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.copyright;

import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.MatchType.AUTHOR_OWNER;
import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.MatchType.LICENSE;
import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType.FIRST_PARTY;
import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType.FORBIDDEN;
import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType.THIRD_PARTY;
import static com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType.UNKNOWN;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput;
import com.google.gerrit.extensions.api.changes.ReviewResult;
import com.google.gerrit.extensions.api.changes.ReviewerInfo;
import com.google.gerrit.extensions.client.Comment;
import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.events.RevisionCreatedListener;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.Match;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.MatchType;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;

/** Utility to report revision findings on the review thread. */
@Singleton
public class CopyrightReviewApi {
  static final ImmutableList<Match> ALWAYS_REVIEW = ImmutableList.of();

  private final Metrics metrics;
  private final Provider<PluginUser> pluginUserProvider;
  private final Provider<CurrentUser> userProvider;
  private final IdentifiedUser.GenericFactory identifiedUserFactory;
  private final ThreadLocalRequestContext requestContext;
  private final GerritApi gApi;

  @Inject
  CopyrightReviewApi(
      Metrics metrics,
      Provider<PluginUser> pluginUserProvider,
      Provider<CurrentUser> userProvider,
      IdentifiedUser.GenericFactory identifiedUserFactory,
      ThreadLocalRequestContext requestContext,
      GerritApi gApi) {
    this.metrics = metrics;
    this.pluginUserProvider = pluginUserProvider;
    this.userProvider = userProvider;
    this.identifiedUserFactory = identifiedUserFactory;
    this.requestContext = requestContext;
    this.gApi = gApi;
  }

  /**
   * Reports failure findings from or about the check_new_config.sh tool on the review thread.
   *
   * <p>If no output found in the commit message, directs the submitter to run the tool and copy its
   * output into the commit message.
   *
   * <p>If the output was found for a different scanner pattern, directs the submitter to run again
   * for the current commit.
   *
   * <p>Otherwise, the duration of the timing run must exceed the configured limit. Describes
   * patterns known to cause problems and directs the submitter to change the pattern.
   *
   * @param pluginName as installed in gerrit
   * @param project identifies the All-Projects config for recording metrics
   * @param oldConfig the prior state of the plugin configuration
   * @param newConfig the new state of the plugin configuration
   * @param event describes the pushed revision with the new configuration
   * @param findings describes the line numbers, validity and timing run durations found
   * @param maxElapsedSeconds the largest allows timing run duration in seconds
   * @throws RestApiException if an error occurs updating the review thread
   */
  ReviewResult reportCommitMessageFindings(
      String pluginName,
      String project,
      ScannerConfig oldConfig,
      ScannerConfig newConfig,
      RevisionCreatedListener.Event event,
      ImmutableList<CommitMessageFinding> findings,
      long maxElapsedSeconds)
      throws RestApiException {
    Preconditions.checkNotNull(newConfig);
    Preconditions.checkNotNull(newConfig.scanner);
    Preconditions.checkArgument(
        oldConfig == null
            || oldConfig.scanner == null
            || !oldConfig.scanner.equals(newConfig.scanner));
    Preconditions.checkArgument(findings.size() != 1 || !findings.get(0).isValid());
    Preconditions.checkArgument(maxElapsedSeconds > 0);

    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    int fromAccountId =
        oldConfig != null && oldConfig.fromAccountId > 0
            ? oldConfig.fromAccountId
            : newConfig.fromAccountId;
    try (ManualRequestContext ctx = getContext(fromAccountId)) {
      ChangeApi cApi = gApi.changes().id(event.getChange().id);
      Map<String, List<CommentInfo>> priorReviewComments = cApi.comments();
      if (priorReviewComments == null) {
        priorReviewComments = ImmutableMap.of();
      }
      HashSet<CommentInfo> priorComments = new HashSet<>();
      priorComments.addAll(priorReviewComments.get("/COMMIT_MSG"));

      ReviewInput ri = new ReviewInput();
      ri.message(getCommitMessageMessage(pluginName, findings, maxElapsedSeconds));
      ImmutableList<CommentInput> comments =
          ImmutableList.copyOf(
              getCommitMessageComments(pluginName, findings, maxElapsedSeconds).stream()
                  .filter(ci -> !priorComments.contains(ci))
                  .toArray(i -> new CommentInput[i]));
      if (!comments.isEmpty()) {
        ri.comments = ImmutableMap.of("/COMMIT_MSG", comments);
      }
      String label = "Code-Review";
      if (!Strings.isNullOrEmpty(oldConfig.reviewLabel)) {
        label = oldConfig.reviewLabel;
      } else if (!Strings.isNullOrEmpty(newConfig.reviewLabel)) {
        label = newConfig.reviewLabel;
      }
      int vote = (findings.size() != 1 || !findings.get(0).isValid()) ? -2 : 2;
      if (vote == 2) {
        long elapsedMicros = findings.get(0).elapsedMicros;
        if (elapsedMicros > maxElapsedSeconds * 1000000) {
          vote = -2;
        } else if (elapsedMicros > 2000000) {
          vote = 1;
        }
      }
      ri.label(label, vote);
      return cApi.current().review(ri);
    }
  }

  /**
   * Returns a {@link com.google.gerrit.server.git.validators.CommitValidationException} describing
   * failure findings from or about the check_new_config.sh tool.
   *
   * <p>If no output found in the commit message, directs the submitter to run the tool and copy its
   * output into the commit message.
   *
   * <p>If the output was found for a different scanner pattern, directs the submitter to run again
   * for the current commit.
   *
   * <p>Otherwise, the duration of the timing run must exceed the configured limit. Describes
   * patterns known to cause problems and directs the submitter to change the pattern.
   *
   * @param pluginName as installed in gerrit
   * @param findings describes the line numbers, validity and timing run durations found
   * @param maxElapsedSeconds the largest allows timing run duration in seconds
   */
  public CommitValidationException getCommitMessageException(
      String pluginName, ImmutableList<CommitMessageFinding> findings, long maxElapsedSeconds) {
    Preconditions.checkArgument(
        findings.size() != 1
            || !findings.get(0).isValid()
            || findings.get(0).elapsedMicros > maxElapsedSeconds * 1000000);
    StringBuilder sb = new StringBuilder();
    sb.append(getCommitMessageMessage(pluginName, findings, maxElapsedSeconds));
    sb.append("\n\n");
    ImmutableList<CommentInput> comments =
        getCommitMessageComments(pluginName, findings, maxElapsedSeconds);
    for (CommentInput ci : comments) {
      if (ci.line != 0) {
        sb.append("commit message line ");
        sb.append(Integer.toString(ci.range.startLine));
        sb.append(":\n");
      }
      sb.append(ci.message);
      sb.append("\n");
    }
    return new CommitValidationException(sb.toString());
  }

  /**
   * Reports validation findings for a proposed new plugin configuration to the review thread for
   * the newly pushed revision.
   *
   * @param pluginName as installed in gerrit
   * @param project identifies the All-Projects config for recording metrics
   * @param path identifies the file to attach messages to (@code gerrit.config or project.config}
   * @param oldConfig the prior state of the plugin configuration
   * @param newConfig the new state of the plugin configuration
   * @param event describes the pushed revision with the new configuration
   * @throws RestApiException if an error occurs updating the review thread
   */
  ReviewResult reportConfigMessages(
      String pluginName,
      String project,
      String path,
      ScannerConfig oldConfig,
      ScannerConfig newConfig,
      RevisionCreatedListener.Event event)
      throws RestApiException {
    Preconditions.checkNotNull(newConfig);
    Preconditions.checkNotNull(newConfig.messages);
    Preconditions.checkArgument(!newConfig.messages.isEmpty());

    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    int fromAccountId =
        oldConfig != null && oldConfig.fromAccountId > 0
            ? oldConfig.fromAccountId
            : newConfig.fromAccountId;
    try (Timer0.Context t0 = metrics.reviewTimer.start();
        Timer1.Context t1 = metrics.reviewTimerByProject.start(project);
        ManualRequestContext ctx = getContext(fromAccountId)) {
      ChangeApi cApi = gApi.changes().id(event.getChange().id);
      StringBuilder message = new StringBuilder();
      message.append(pluginName);
      message.append(" plugin issues parsing new configuration");
      ReviewInput ri = new ReviewInput().message(message.toString());

      Map<String, List<CommentInfo>> priorComments = cApi.comments();
      if (priorComments == null) {
        priorComments = ImmutableMap.of();
      }

      int numComments = 0;
      ImmutableMap.Builder<String, List<CommentInput>> comments = ImmutableMap.builder();
      for (CommitValidationMessage m : newConfig.messages) {
        message.setLength(0);
        message.append(m.getType().toString());
        message.append(" ");
        message.append(m.getMessage());
        CommentInput ci = new CommentInput();
        ci.line = 0;
        ci.unresolved = true;
        ci.message = message.toString();
        if (containsComment(priorComments.get(path), ci)) {
          continue;
        }
        comments.put(path, ImmutableList.of(ci));
        numComments++;
      }
      if (numComments > 0) {
        ri.comments = comments.build();
      }
      metrics.commentCount.incrementBy((long) numComments);
      metrics.commentCountByProject.incrementBy(project, (long) numComments);
      return cApi.current().review(ri);
    }
  }

  /**
   * Reports {@link CopyrightValidator} findings from a scanned revision on its review thread.
   *
   * @param project identifies the project where change pushed for recording metrics
   * @param scannerConfig the state of the plugin configuration and scanner
   * @param event describes the pushed revision scanned by the plugin
   * @param findings maps each scanned file to the copyright matches found by the scanner
   * @throws RestApiException if an error occurs updating the review thread
   */
  ReviewResult reportScanFindings(
      String project,
      ScannerConfig scannerConfig,
      RevisionCreatedListener.Event event,
      Map<String, ImmutableList<Match>> findings)
      throws RestApiException {
    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    try (Timer0.Context t0 = metrics.reviewTimer.start();
        Timer1.Context t1 = metrics.reviewTimerByProject.start(project);
        ManualRequestContext ctx = getContext(scannerConfig.fromAccountId)) {
      boolean tpAllowed = scannerConfig.isThirdPartyAllowed(project);
      boolean reviewRequired = false;
      for (Map.Entry<String, ImmutableList<Match>> entry : findings.entrySet()) {
        if (entry.getValue() == ALWAYS_REVIEW) {
          reviewRequired = true;
          break;
        }
        PartyType pt = partyType(entry.getValue());
        if (pt.compareTo(THIRD_PARTY) > 0) {
          reviewRequired = true;
          break;
        }
        if (pt == THIRD_PARTY && !tpAllowed) {
          reviewRequired = true;
          break;
        }
      }
      ChangeApi cApi = gApi.changes().id(event.getChange().id);
      ReviewInput ri =
          new ReviewInput()
              .message("Copyright scan")
              .label(scannerConfig.reviewLabel, reviewRequired ? -1 : +2);

      if (reviewRequired) {
        List<ReviewerInfo> reviewers = cApi.reviewers();
        ri = addReviewers(reviewers, ri, scannerConfig.ccs, ReviewerState.CC);
        ri = addReviewers(reviewers, ri, scannerConfig.reviewers, ReviewerState.REVIEWER);
      }
      ImmutableMap.Builder<String, List<CommentInput>> comments = ImmutableMap.builder();
      if (reviewRequired) {
        ri = ri.message("This change requires copyright review.");
      } else {
        ri = ri.message("This change appears to comply with copyright requirements.");
      }
      Map<String, List<CommentInfo>> priorComments = cApi.comments();
      if (priorComments == null) {
        priorComments = ImmutableMap.of();
      }

      int numCommentsAdded = 0;
      for (Map.Entry<String, ImmutableList<Match>> entry : findings.entrySet()) {
        ImmutableList<CommentInput> newComments = null;
        if (entry.getValue() == ALWAYS_REVIEW) {
          CommentInput ci = new CommentInput();
          ci.line = 0;
          ci.unresolved = true;
          ci.message = entry.getKey() + " always requires copyright review";
          if (containsComment(priorComments.get(entry.getKey()), ci)) {
            continue;
          }
          newComments = ImmutableList.of(ci);
        } else {
          PartyType pt = partyType(entry.getValue());
          newComments = reviewComments(project, pt, tpAllowed, entry.getValue());
          List<CommentInfo> prior = priorComments.get(entry.getKey());
          newComments =
              ImmutableList.copyOf(
                  newComments.stream()
                      .filter(ci -> !containsComment(prior, ci))
                      .toArray(i -> new CommentInput[i]));
          if (newComments.isEmpty()) {
            continue;
          }
        }
        numCommentsAdded += newComments.size();
        comments.put(entry.getKey(), newComments);
      }

      if (numCommentsAdded > 0) {
        ri.comments = comments.build();
      }
      metrics.commentCount.incrementBy((long) numCommentsAdded);
      metrics.commentCountByProject.incrementBy(project, (long) numCommentsAdded);
      return cApi.current().review(ri);
    }
  }

  /**
   * Returns the {@link com.google.gerrit.server.CurrentUser} seeming to send the review comments.
   *
   * <p>Impersonates {@code fromAccountId} if configured by {@code fromAccountId =} in plugin
   * configuration -- falling back to the identity of the user pushing the revision.
   */
  CurrentUser getSendingUser(int fromAccountId) {
    PluginUser pluginUser = pluginUserProvider.get();
    return fromAccountId <= 0
        ? userProvider.get()
        : identifiedUserFactory.runAs(null, Account.id(fromAccountId), pluginUser);
  }

  /**
   * Returns 1 of 3 review messages depending on the check_new_config.sh tool output.
   *
   * @param pluginName as installed in gerrit
   * @param findings describes the line numbers, validity and timing run durations found
   */
  private String getCommitMessageMessage(
      String pluginName, ImmutableList<CommitMessageFinding> findings, long maxElapsedSeconds) {
    StringBuilder sb = new StringBuilder();
    if (findings.isEmpty()) {
      sb.append(pluginName);
      sb.append(" plugin: match patterns have changed; please run check_new_config tool");
    } else if (findings.size() == 1 && findings.get(0).isValid()) {
      long elapsedMicros = findings.get(0).elapsedMicros;
      if (elapsedMicros > maxElapsedSeconds * 1000000) {
        sb.append("check_new_config: problem pattern detected");
      } else if (elapsedMicros > 2000000) {
        sb.append("check_new_config: possible problem pattern detected");
      } else if (elapsedMicros > 1000000) {
        sb.append("check_new_config: possibly okay");
      } else {
        sb.append("check_new_config: okay");
      }
    } else {
      sb.append("check_new_config: results for wrong commit; please run again for current");
    }
    return sb.toString();
  }

  /**
   * Returns one or more of 3 review comment versions based on the check_new_config.sh tool output.
   *
   * @param pluginName as installed in gerrit
   * @param findings describes the line numbers, validity and timing run durations found
   * @param maxElapsedSeconds the largest allows timing run duration in seconds
   */
  private ImmutableList<CommentInput> getCommitMessageComments(
      String pluginName, ImmutableList<CommitMessageFinding> findings, long maxElapsedSeconds) {
    ImmutableList.Builder<CommentInput> comments = ImmutableList.builder();
    StringBuilder sb = new StringBuilder();
    CommentInput ci = new CommentInput();
    if (findings.isEmpty()) {
      sb.append("While most patterns are fine, some patterns can force your gerrit server\n");
      sb.append("to work too hard. To protect your server, there is a tool that can\n");
      sb.append("detect these patterns before the configuration gets submitted.\n\n");
      sb.append("Please use git to download the tool from:\n");
      sb.append("https://gerrit.googlesource.com/plugins/copyright/+/refs/heads/master\n\n");
      sb.append("After downloading, run tools/check_new_config.sh (requires bazel):\n");
      sb.append("<path>/tools/check_new_config.sh '");
      sb.append(pluginName);
      sb.append("' '<path>/project.config'\n");
      sb.append("and copy it's output to your commit message.\n\n");
      sb.append("e.g. if your local All-Projects is at workspace/All-Projects and if you\n");
      sb.append("downloaded plugins/copyright to workspace/copyright, you might run:\n");
      sb.append("../copyright/tools/check_new_config.sh '");
      sb.append(pluginName);
      sb.append("' project.config\n");
      sb.append("from the workspace/All-Projects directory.\n");
      ci.line = 0;
      ci.unresolved = true;
      ci.message = sb.toString();
      comments.add(ci);
    } else if (findings.size() == 1 && findings.get(0).isValid()) {
      CommitMessageFinding finding = findings.get(0);
      if (finding.elapsedMicros > maxElapsedSeconds * 1000000) {
        sb.append("Scanning the test file took longer than ");
        sb.append(Long.toString(maxElapsedSeconds));
        sb.append(" seconds.");
        if (finding.elapsedMicros - (maxElapsedSeconds * 1000000) > 1000000) {
          sb.append(" (");
          sb.append(Long.toString(finding.elapsedMicros / 1000000));
          sb.append(" seconds)");
        }
        sb.append("\n\nThis is much longer than usual even on a slower, modern computer.\n\n");
        sb.append("The result suggests a pattern that causes excessive backtracking.\n");
        sb.append(typicalBacktrackingCauses());
        sb.append("\nPlease fix any problematic patterns and try again.\n");
      } else if (finding.elapsedMicros > 2000000) {
        sb.append("Scanning the test file took longer than 2 seconda. (");
        if (finding.elapsedMicros > 3000000) {
          sb.append(Long.toString(finding.elapsedMicros / 1000000));
          sb.append(" seconds)");
        } else {
          sb.append(Long.toString(finding.elapsedMicros / 1000));
          sb.append(" ms)");
        }
        sb.append("\n\nThe result suggests a pattern that might cause excessive backtracking.\n");
        sb.append(typicalBacktrackingCauses());
        sb.append("\nPlease try to fix any problematic patterns before proceeding.\n");
      } else if (finding.elapsedMicros > 1000000) {
        sb.append("Scanning the test file took just longer than a second. (");
        sb.append(Long.toString(finding.elapsedMicros / 1000));
        sb.append("ms)");
        sb.append("\n\nThe result is a little longer than ideal.\n\n");
        sb.append(typicalBacktrackingCauses());
        sb.append("\n\nCompare with the current config, and if this config is signigicantly\n");
        sb.append("slower, consider changing whatever pattern causes the problem.\n");
      } else if (finding.elapsedMicros > 1000) {
        sb.append("Scanning the test file took ");
        sb.append(Long.toString(finding.elapsedMicros / 1000));
        sb.append("ms.");
      } else {
        sb.append("Scanning the test file took ");
        sb.append(Long.toString(finding.elapsedMicros));
        sb.append(" microsends.");
      }
      ci.line = finding.endLine;
      ci.range = new CommentInput.Range();
      ci.range.startLine = finding.startLine;
      ci.range.endLine = finding.endLine;
      ci.range.startCharacter = finding.startCol;
      ci.range.endCharacter = finding.endCol;
      ci.unresolved = finding.elapsedMicros > 1000000;
      ci.message = sb.toString();
      comments.add(ci);
    } else {
      for (CommitMessageFinding finding : findings) {
        sb.setLength(0);
        sb.append("'");
        sb.append(finding.text.trim());
        sb.append("'\nis not a result for the patterns in the current revision");
        ci.line = finding.endLine;
        ci.range = new CommentInput.Range();
        ci.range.startLine = finding.startLine;
        ci.range.endLine = finding.endLine;
        ci.range.startCharacter = finding.startCol;
        ci.range.endCharacter = finding.endCol;
        ci.unresolved = true;
        ci.message = sb.toString();
        comments.add(ci);
        ci = new CommentInput();
      }
    }
    return comments.build();
  }

  public static String typicalBacktrackingCauses() {
    StringBuilder sb = new StringBuilder();
    sb.append("Typical causes of excessive backtracking include:\n");
    sb.append("  1. unbounded repetitions of wildcards or\n");
    sb.append("  2. zero-length look-ahead/look-behind patterns\n\n");
    sb.append("Wildcards:\n");
    sb.append("  The scanner automatically handles .* and .+ patterns, but it's\n");
    sb.append("  possible to accidentally compose equivalents or near-equivalents:\n");
    sb.append("  e.g. (?:[a]|[^a])* or [\\\\s\\\\p{N}\\\\p{L}\\\\p{P}]+ match nearly everything\n");
    sb.append("  If your new pattern contains something similar, consider using .* for\n");
    sb.append("  automatic handling instead, or use a smaller character class.\n\n");
    sb.append("Unbounded repetitions:\n");
    sb.append("  If your new pattern uses * or + for unlimited repetitions, consider\n");
    sb.append("  using a more limited repetition like {0,10} or {1,50} that is long\n");
    sb.append("  enough to match what you need but short enough to scan quickly.\n\n");
    sb.append("Zero-length look-ahead or look-behind:\n");
    sb.append("  Patterns like (?!word), (?=word), (?<!word). (?<=word) etc. can cause\n");
    sb.append("  excessive backtracking too. Sometimes, it is faster to match a little\n");
    sb.append("  more than needed and use an excludePattern to eliminate unwanted hits.\n");
    sb.append("  e.g. forbiddenPattern = owner some pattern \\p{L}*\n");
    sb.append("       excludePattern = some pattern word\n");
    return sb.toString();
  }

  private ManualRequestContext getContext(int fromAccountId) {
    PluginUser pluginUser = pluginUserProvider.get();
    CurrentUser user =
        fromAccountId <= 0
            ? userProvider.get()
            : identifiedUserFactory.runAs(null, Account.id(fromAccountId), pluginUser);
    return new ManualRequestContext(user, requestContext);
  }

  /**
   * Returns a modified {@link com.google.gerrit.extensions.api.changes.ReviewInput} after adding
   * {@code reviewers} as {@code type} CC or REVIEWER.
   */
  @VisibleForTesting
  ReviewInput addReviewers(
      List<ReviewerInfo> existingReviewers,
      ReviewInput ri,
      Iterable<String> reviewers,
      ReviewerState type) {
    for (String reviewer : reviewers) {
      if (containsReviewer(existingReviewers, reviewer)) {
        continue;
      }
      ri = ri.reviewer(reviewer, type, true);
    }
    return ri;
  }

  /** Returns true if {@code priorComments} already includes a comment identical to {@code ci}. */
  @VisibleForTesting
  boolean containsComment(Iterable<? extends Comment> priorComments, CommentInput ci) {
    if (priorComments == null) {
      return false;
    }
    for (Comment prior : priorComments) {
      if (Objects.equals(prior.line, ci.line)
          && Objects.equals(prior.range, ci.range)
          && Objects.equals(prior.message, ci.message)) {
        return true;
      }
    }
    return false;
  }

  /** Returns true if {@code priorReviewers} already includes {@code reviewer}. */
  boolean containsReviewer(Iterable<? extends ReviewerInfo> priorReviewers, String reviewer) {
    if (priorReviewers == null) {
      return false;
    }
    for (ReviewerInfo prior : priorReviewers) {
      if (Objects.equals(prior.username, reviewer) || Objects.equals(prior.name, reviewer)
          || Objects.equals(prior.email, reviewer)
          || Objects.equals(Integer.toString(prior._accountId), reviewer)) {
        return true;
      }
      if (prior.secondaryEmails != null && prior.secondaryEmails.contains(reviewer)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Puts the pieces together from a scanner finding to construct a coherent human-reable message.
   *
   * @param project describes the project or repository where the revision was pushed
   * @param overallPt identifies the calculated {@link
   *     com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType} for all of the
   *     findings in the file. e.g. 1p license + 3p owner == 1p, no license + 3p owner == 3p
   * @param pt identifies the {@code PartyType} of the current finding
   * @param mt identifies the {@link
   *     com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.MatchType} of the current
   *     finding. i.e. AUTHOR_OWNER or LICENSE
   * @param tpAllowed is true if {@code project} allows third-party code
   * @param text of the message for the finding
   */
  private String buildMessage(
      String project,
      PartyType overallPt,
      PartyType pt,
      MatchType mt,
      boolean tpAllowed,
      StringBuilder text) {
    StringBuilder message = new StringBuilder();
    switch (pt) {
      case FIRST_PARTY:
        message.append("First-party ");
        break;
      case THIRD_PARTY:
        message.append("Third-party ");
        break;
      case FORBIDDEN:
        message.append("Disapproved ");
        break;
      default:
        message.append("Unrecognized ");
        break;
    }
    message.append(mt == AUTHOR_OWNER ? "author or owner " : "license ");
    if (pt == THIRD_PARTY && overallPt != FIRST_PARTY) {
      if (!tpAllowed) {
        message.append("dis");
      }
      message.append("allowed in repository ");
      message.append(project);
    }
    message.append(":\n\n");
    message.append(text);
    return message.toString();
  }

  /**
   * Converts the scanner findings in {@code matches} into human-readable review comments.
   *
   * @param project the project or repository to which the revision was pushed
   * @param pt the calculated overall {@link
   *     com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType} for the findings
   *     e.g. 1p license + 3p owner = 1p, no license + 3p owner = 3p
   * @param tpAllowed is true if {@code project} allows third-party code
   * @param matches describes the location and types of matches found in a file
   * @return a list of {@link com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput} to
   *     add to the {@link com.google.gerrit.extensions.api.changes.ReviewInput} to add to the
   *     review thread for the current patch set.
   */
  @VisibleForTesting
  ImmutableList<CommentInput> reviewComments(
      String project, PartyType pt, boolean tpAllowed, Iterable<Match> matches) {
    ImmutableList.Builder<CommentInput> builder = ImmutableList.builder();
    CommentInput ci = null;
    PartyType previousPt = UNKNOWN;
    MatchType previousMt = LICENSE;
    StringBuilder text = new StringBuilder();
    for (Match m : matches) {
      if (ci == null
          || previousPt != m.partyType
          || m.endLine > ci.range.startLine + 60
          || m.startLine > ci.range.endLine + 40) {
        if (ci != null) {
          ci.message = buildMessage(project, pt, previousPt, previousMt, tpAllowed, text);
          builder.add(ci);
        }
        ci = new CommentInput();
        boolean allowed =
            m.partyType == FIRST_PARTY
                || (m.partyType == THIRD_PARTY && tpAllowed)
                || (m.partyType == THIRD_PARTY && m.matchType == AUTHOR_OWNER && pt == FIRST_PARTY);
        ci.unresolved = !allowed;
        ci.range = new Comment.Range();
        ci.line = m.endLine;
        ci.range.startLine = m.startLine;
        ci.range.endLine = m.endLine;
        ci.range.startCharacter = 0;
        ci.range.endCharacter = 0;
        previousPt = m.partyType;
        previousMt = m.matchType;
        text.setLength(0);
        text.append(m.text);
        continue;
      }
      text.append("...");
      text.append(m.text);
      // an author or owner inside a license declaration is a normal part of a license declaration
      if (m.matchType == LICENSE) {
        previousMt = LICENSE;
      }
      if (m.startLine < ci.range.startLine) {
        ci.range.startLine = m.startLine;
      }
      if (m.endLine > ci.range.endLine) {
        ci.range.endLine = m.endLine;
        ci.line = m.endLine;
      }
    }
    if (ci != null) {
      ci.message = buildMessage(project, pt, previousPt, previousMt, tpAllowed, text);
      builder.add(ci);
    }
    return builder.build();
  }

  /**
   * Calculates and returns the overall {@link
   * com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType} for the copyright
   * scanner findings in {@code matches}.
   */
  @VisibleForTesting
  PartyType partyType(Iterable<Match> matches) {
    PartyType pt = PartyType.FIRST_PARTY;
    boolean hasThirdPartyOwner = false;
    boolean hasFirstPartyLicense = false;
    for (Match match : matches) {
      if (match.partyType == PartyType.THIRD_PARTY && match.matchType == MatchType.AUTHOR_OWNER) {
        hasThirdPartyOwner = true;
      } else if (match.partyType == PartyType.FIRST_PARTY && match.matchType == MatchType.LICENSE) {
        hasFirstPartyLicense = true;
      } else if (match.partyType.compareTo(pt) > 0) {
        pt = match.partyType;
      }
    }
    if (pt == PartyType.FIRST_PARTY && hasThirdPartyOwner && !hasFirstPartyLicense) {
      return PartyType.THIRD_PARTY;
    }
    return pt;
  }

  /**
   * Found {@code main} output in the commit message.
   *
   * <p>Each finding identifies the position in the commit message, the validity for the current
   * scanner pattern, and the large file scan duration if valid.
   */
  public static class CommitMessageFinding {
    private static final Pattern NL = Pattern.compile("\n", Pattern.MULTILINE | Pattern.DOTALL);

    /** The character offset into the commit message where the finding starts. */
    public final int start;
    /** The character offset into the commit message where the finding ends. */
    public final int end;
    /** The found text apparently matching {@code main} output. */
    public final String text;
    /** How long in microseconds it took to scan a large file, or -1 if scan with other pattern. */
    public final long elapsedMicros;

    /** The line number of the start of the finding in the commit message. */
    public final int startLine;
    /** The column (0-based) of the start of the finding in the commit message. */
    public final int startCol;
    /** The line number of the end of the finding in the commit message. */
    public final int endLine;
    /** The column (0-based) of the end of the finding in the commit message. */
    public final int endCol;

    /** Returns true when {@code elapsedMicros} reflects the current scanner pattern. */
    public boolean isValid() {
      return elapsedMicros >= 0;
    }

    /** A finding for the current scanner pattern with relevant {@code elapsedMicros}. */
    CommitMessageFinding(String commitMsg, String text, String elapsedMicros, int start, int end) {
      this.start = start;
      this.end = end;
      this.text = text;
      this.elapsedMicros = Long.parseLong(elapsedMicros, 16);

      Matcher m = NL.matcher(commitMsg);
      int line = 1;
      int lineStart = 0;
      int startLine = 0;
      int startCol = -1;
      int endLine = 0;
      int endCol = -1;
      while (m.find()) {
        if (m.start() > start) {
          startLine = line;
          startCol = start - lineStart;
        }
        if (m.start() > end) {
          endLine = line;
          endCol = end - lineStart;
          break;
        }
        line++;
        lineStart = m.end();
      }
      if (startLine == 0) {
        startLine = line;
        startCol = start - lineStart;
      }
      if (endLine == 0) {
        endLine = line;
        endCol = end - lineStart;
      }
      this.startLine = startLine;
      this.startCol = startCol;
      this.endLine = endLine;
      this.endCol = endCol;
    }

    /** A finding for a different scanner pattern -- {@code elapsedMicros} not relevant. */
    CommitMessageFinding(String commitMsg, String text, int start, int end) {
      this(commitMsg, text, "-1", start, end);
    }
  }
}
