// 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.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
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.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.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.metrics.Counter0;
import com.google.gerrit.metrics.Counter1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.PluginUser;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.restapi.change.ListChangeComments;
import com.google.gerrit.server.restapi.change.PostReview;
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.concurrent.TimeUnit;
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 ChangeNotes.Factory changeNotesFactory;
  private final ChangeResource.Factory changeResourceFactory;
  private final PatchSetUtil psUtil;
  private final PostReview postReview;
  private final ListChangeComments listChangeComments;

  @Singleton
  static class Metrics {
    final Counter0 reviewCount;
    final Counter0 commentCount;
    final Timer0 reviewTimer;
    final Counter1 reviewCountByProject;
    final Counter1 commentCountByProject;
    final Timer1 reviewTimerByProject;

    @Inject
    Metrics(MetricMaker metricMaker) {
      Field<String> project = Field.ofString("project", "project name");
      reviewCount =
          metricMaker.newCounter(
              "plugin/copyright/review_count",
              new Description("Total number of posted reviews").setRate().setUnit("reviews"));
      commentCount =
          metricMaker.newCounter(
              "plugin/copyright/comment_count",
              new Description("Total number of posted review comments")
                  .setRate()
                  .setUnit("comments"));
      reviewTimer =
          metricMaker.newTimer(
              "plugin/copyright/review_latency",
              new Description("Time spent posting reviews to revisions")
                  .setCumulative()
                  .setUnit(Units.MICROSECONDS));
      reviewCountByProject =
          metricMaker.newCounter(
              "plugin/copyright/review_count_by_project",
              new Description("Total number of posted reviews").setRate().setUnit("reviews"),
              project);
      commentCountByProject =
          metricMaker.newCounter(
              "plugin/copyright/comment_count_by_project",
              new Description("Total number of posted review comments")
                  .setRate()
                  .setUnit("comments"),
              project);
      reviewTimerByProject =
          metricMaker.newTimer(
              "plugin/copyright/review_latency_by_project",
              new Description("Time spent posting reviews to revisions")
                  .setCumulative()
                  .setUnit(Units.MICROSECONDS),
              project);
    }
  }

  @Inject
  CopyrightReviewApi(
      Metrics metrics,
      Provider<PluginUser> pluginUserProvider,
      Provider<CurrentUser> userProvider,
      IdentifiedUser.GenericFactory identifiedUserFactory,
      ChangeNotes.Factory changeNotesFactory,
      ChangeResource.Factory changeResourceFactory,
      PatchSetUtil psUtil,
      PostReview postReview,
      ListChangeComments listChangeComments) {
    this.metrics = metrics;
    this.pluginUserProvider = pluginUserProvider;
    this.userProvider = userProvider;
    this.identifiedUserFactory = identifiedUserFactory;
    this.changeNotesFactory = changeNotesFactory;
    this.changeResourceFactory = changeResourceFactory;
    this.psUtil = psUtil;
    this.postReview = postReview;
    this.listChangeComments = listChangeComments;
  }

  /**
   * 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);

    long startNanos = System.nanoTime();
    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    int fromAccountId =
        oldConfig != null && oldConfig.fromAccountId > 0
            ? oldConfig.fromAccountId
            : newConfig.fromAccountId;
    ChangeResource change = getChange(event, fromAccountId);
    Map<String, List<CommentInfo>> priorReviewComments = getComments(change);
    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 review(change, 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());

    long startNanos = System.nanoTime();
    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    try {
      int fromAccountId =
          oldConfig != null && oldConfig.fromAccountId > 0
              ? oldConfig.fromAccountId
              : newConfig.fromAccountId;
      ChangeResource change = getChange(event, fromAccountId);
      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 = getComments(change);
      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 review(change, ri);
    } finally {
      long elapsedMicros = (System.nanoTime() - startNanos) / 1000;
      metrics.reviewTimer.record(elapsedMicros, TimeUnit.MICROSECONDS);
      metrics.reviewTimerByProject.record(project, elapsedMicros, TimeUnit.MICROSECONDS);
    }
  }

  /**
   * 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 {
    long startNanos = System.nanoTime();
    metrics.reviewCount.increment();
    metrics.reviewCountByProject.increment(project);

    try {
      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;
        }
      }
      ChangeResource change = getChange(event, scannerConfig.fromAccountId);
      ReviewInput ri =
          new ReviewInput()
              .message("Copyright scan")
              .label(scannerConfig.reviewLabel, reviewRequired ? -1 : +2);

      if (reviewRequired) {
        ri = addReviewers(ri, scannerConfig.ccs, ReviewerState.CC);
        ri = addReviewers(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 = getComments(change);
      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 review(change, ri);
    } finally {
      long elapsedMicros = (System.nanoTime() - startNanos) / 1000;
      metrics.reviewTimer.record(elapsedMicros, TimeUnit.MICROSECONDS);
      metrics.reviewTimerByProject.record(project, elapsedMicros, TimeUnit.MICROSECONDS);
    }
  }

  /**
   * 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();
  }

  /**
   * Constructs a {@link com.google.gerrit.server.change.ChangeResource} from the notes log for the
   * change onto which a new revision was pushed.
   *
   * @param event describes the newly pushed revision
   * @param fromAccountId identifies the configured user to impersonate when sending review comments
   * @throws RestApiException if an error occurs looking up the notes log for the change
   */
  private ChangeResource getChange(RevisionCreatedListener.Event event, int fromAccountId)
      throws RestApiException {
    try {
      CurrentUser fromUser = getSendingUser(fromAccountId);
      ChangeNotes notes = changeNotesFactory.createChecked(Change.id(event.getChange()._number));
      return changeResourceFactory.create(notes, fromUser);
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      throw e instanceof RestApiException
          ? (RestApiException) e
          : new RestApiException("Cannot load change", e);
    }
  }

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

  /**
   * Retrieves all of the prior review comments already attached to {@code change}.
   *
   * @throws RestApiException if an error occurs retrieving the comments
   */
  private Map<String, List<CommentInfo>> getComments(ChangeResource change)
      throws RestApiException {
    try {
      return listChangeComments.apply(change);
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      throw e instanceof RestApiException
          ? (RestApiException) e
          : new RestApiException("Cannot list comments", e);
    }
  }

  /**
   * Adds the code review described by {@code ri} to the review thread of {@code change}.
   *
   * @throws RestApiException if an error occurs updating the review thread
   */
  private ReviewResult review(ChangeResource change, ReviewInput ri) throws RestApiException {
    try {
      PatchSet ps = psUtil.current(change.getNotes());
      if (ps == null) {
        throw new ResourceNotFoundException(IdString.fromDecoded("current"));
      }
      RevisionResource revision = RevisionResource.createNonCacheable(change, ps);
      return postReview.apply(revision, ri).value();
    } catch (Exception e) {
      Throwables.throwIfUnchecked(e);
      throw e instanceof RestApiException
          ? (RestApiException) e
          : new RestApiException("Cannot post review", e);
    }
  }

  /** 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;
  }

  /**
   * 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);
    }
  }
}
