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

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Immutable file scanner for copyrights classifying the copyright matches it finds.
 *
 * <p>In general, configure the first-party (1p) and forbidden owners, and any generic owner matches
 * get classified as third-party (3p) automatically. Generally, only configure third-party (3p)
 * owners that the generic pattern will not match for some reason.
 *
 * <p>Licenses are different. Unknown licenses get identified as unknown and treated the same as
 * forbidden. Configure all of the known first-party (1p), third-party (3p) and forbidden licenes.
 *
 * <p>Configure the scanner using simplified regular expressions. The scanner will replace sequences
 * of whitespace with a regular sub-expression matching sequences of whitespace or comment
 * characters. Because the scanner makes this transformation, avoid including whitespace inside
 * character classes.
 *
 * <p>e.g. use "Android Open(?: |-)Source Project" not "Android Open[- ]Source Project"
 *
 * <p>When classifying matches as 1p, 3p or forbidden, the scanner looks for complete matches of
 * configured patterns. i.e. "re.match()" not "re.find()"
 *
 * <p>It's useful to include wildcards in configured patterns to match sub-sequences in generic
 * matches, but these can cause excessive backtracking leading to performance problems or even stack
 * exhaustion. The scanner replaces the wildcards '.*' and '.+' with expressions matching a more
 * limited set of characters for a shorter length that will generally match what is expected.
 *
 * <p>This allows simple configuration patterns like ".*Licen[cs]ed under the Apache Licen[cs]e,?"
 * without the risks normally caused by wildcard patterns.
 */
public final class CopyrightScanner {

  private final Pattern copyright; // Full regular expression for scanner to match.
  private final ImmutableList<Pattern> firstPartyLicenses; // Match 1p licenses.
  private final ImmutableList<Pattern> thirdPartyLicenses; // Match 3p licenses.
  private final ImmutableList<Pattern> forbiddenLicenses; // Match forbidden licences.
  private final ImmutableList<Pattern> firstPartyOwners; // Match 1p authors/matches.
  private final ImmutableList<Pattern> thirdPartyOwners; // Match 3p authors/matches.
  private final ImmutableList<Pattern> forbiddenOwners; // Match forbidden authors.
  private final ImmutableList<Pattern> contractWords; // Match license words.
  private final ImmutableList<Pattern> excludePatterns; // Exclude when found.

  // Most files that have a copyright or license declaration have 1 of them -- or at most 2 or 3.
  // NOTICE files can have thousands all derived from other files in the repository. No need to find
  // them all. Picked a small multiple of the expected number of licenses per file to catch any
  // long-tail files without wasting much effort on derivative NOTICE files etc.
  private static final int MATCH_THRESHOLD = 10;

  // Determined empirically by scanning millions of files on several hosts and looking at the offset
  // of the first matched copyright or license declaration. A couple .cpp files have copyright
  // declarations near the end of the file for some function or class copied from a third party.
  //
  // The only files where the first match appeared later than 230k or so were a few multi-gigabyte
  // build images derived entirely from other files in the repository. Picked a power of 2 large
  // enough to report all or virtually all of the source files with copyright declarations; even if
  // it doesn't report all of the declarations in the largest source files.
  //
  // There is an obvious trade-off for performance here. Increasing the maximum search length beyond
  // this threshold makes little or no difference for detecting problematic licenses, but does
  // increase scan durations at least linearly for larger files. Reducing the maximum search length
  // significantly below this threshold increases the risk a problematic license will go undetected.
  private static final int MAX_SEARCH_LENGTH = 256 * 1024;

  // All of the MAX parameters below have been chosen empirically similar to MATCH_SEARCH_LENGTH to
  // minimize computing cost while still catching virtually all of the important matches.

  /** Maximum length of consecutive text characters to match. */
  private static final int MAX_NAME_LENGTH = CopyrightPatterns.MAX_NAME_LENGTH;
  /** Maximum number of potential names to match. */
  private static final int MAX_NAME_REPETITION = CopyrightPatterns.MAX_NAME_REPETITION;
  /** Maximum length of consecutive space/comment characters to match. */
  private static final int MAX_SPACE_LENGTH = CopyrightPatterns.MAX_SPACE_LENGTH;
  /** Maximum repetition of potential dates to match. Might have to revisit this in future. */
  private static final int MAX_DATE_REPETITION = CopyrightPatterns.MAX_DATE_REPETITION;

  /** Regular expression matching whitespace or a comment character. */
  private static final String WS = CopyrightPatterns.WS;
  /** Regular expression matching whitespace, a comment character, or punctuation. */
  private static final String WSPCT = CopyrightPatterns.WSPCT;
  /** Regular experssion matching a web address. */
  private static final String URL = CopyrightPatterns.URL;
  /** Regular expression matching a text or email address. */
  public static final String NAME = CopyrightPatterns.NAME;
  /** Regular expression matching an UPPERCASE text. */
  public static final String UPPER_NAME = CopyrightPatterns.UPPER_NAME;
  /** Regular expression matching a Proper Case text. */
  public static final String PROPER_NAME = CopyrightPatterns.PROPER_NAME;
  /** Regular expression matching any text, email address, or quote character. */
  private static final String ANY_CHAR = CopyrightPatterns.ANY_CHAR;
  /** Regular expression matching any text, email address, or quoted string. */
  public static final String ANY_WORD = CopyrightPatterns.ANY_WORD;

  /**
   * Regular expressions to match arbitrary contract words.
   *
   * <p>Purposefully pushed the definition of common contract words to the lowest levels of the
   * library to make it difficult--but not impossible--to customize the word list.
   *
   * <p>There are many words one can think of that are common to license contracts that do not
   * appear here. For example, "grant" and "permission" lead to many false positives due to their
   * use associated with ACLs and visibility etc. The word "contributed" appears so many times in
   * .xml files in the Android code base that it adds significant latency and had to be removed.
   *
   * <p>Most license declarations will have multiple of these words so if a particular word causes a
   * problem in a particular code base, it is probably okay to remove it for all code bases without
   * too large a reduction in true positives. But please, check first.
   *
   * <p>Take care adding new words to make sure they do increase the number of true positives
   * without causing other problems. Remember that the existing word list was arrived at empirically
   * by adding many candidates and then pruning.
   *
   * <p>If the word lists really must diverge among different code bases, make the 2nd constructor
   * public, and provide different word lists at a higher level.
   */
  private static final ImmutableList<String> CONTRACT_WORDS =
      ImmutableList.of(
          "agree(?:s|d|ment)?",
          "amendments?",
          "applicable laws?",
          "any manner",
          "auth?or(?:s|ed|ship)?:?(?-i: \\p{Lu}\\p{Ll}*){2,5}",
          "breach",
          "(?:(?:required|return|allocated|allowed|contributed|copyrighted|generated|provided"
              + "|raised|understandable|used|written) )?by:? @[-\\p{L}\\p{N}._]+",
          "(?:(?:required|return|allocated|allowed|contributed|copyrighted|generated|provided"
              + "|raised|understandable|used|written) )?by:? [-\\p{L}\\p{N}._]+@[-\\p{L}\\p{N}._]+",
          "(?:(?:required|return|allocated|allowed|contributed|copyrighted|generated|provided"
              + "|raised|understandable|used|written) )?by:?(?-i: \\p{Lu}\\p{Ll}*){2,5}",
          "charge for",
          "constitut(?:e|es|ed|ing)",
          "contract(?:s|ed|ing|ual|ually)?",
          // contributed removed -- frequent appearance in large .xml files increases latency
          "contribut(?:e|es|or|ors|ion|ions)",
          "copyleft",
          "\\p{L}+ copyright(?:able)? \\p{L}+",
          "damages",
          "derivative",
          "disclaim(?:s|ed|er)?",
          "endorsements?",
          " [(]?EUPL[)]? ",
          "exemplary",
          "expressly",
          "fitness",
          "govern(?:s|ed|ing)?",
          "here(?:by|under)",
          "herein(?:after)?",
          "however caused",
          "incidental",
          "infring(?:e|es|ed|ing)",
          "injury",
          "jurisdictions?",
          "lawful",
          "liable",
          "liabilit(?:ies|y)",
          "(?:re)?licen[cs](?:e(?![:])|es|ed|ing|or)",
          "litigation",
          "merchantability",
          "must agree",
          "negligen(?:ce|t)",
          "no event",
          "no provision",
          "(?:non|un)enforce(?:s|d|able|ability)?",
          "nonexclusive",
          "notwithstanding",
          "obligations?",
          "otherwise agreed",
          "perpetu(?:al|ity)",
          "phonorecords?",
          "prior written",
          "provisions",
          "public domain",
          "(?-i:(?:" + UPPER_NAME + " ){0,5}PUBLIC LICEN[CS]E)",
          "(?-i:(?:" + PROPER_NAME + " ){0,5}Public Licen[cs]e)",
          "punitive",
          "pursuant",
          "redistribut(?:e|ion)",
          "right to",
          "royalties",
          "set forth",
          " [(]?SISSL[)]? ",
          "SPDX-License-Identifier[:]?",
          "stoppage",
          "terms and conditions",
          "the laws of",
          "third party",
          "tort(?:s|ious)?",
          "trademark",
          "waive(?:s|d|r)?",
          "warrant(?:s|y|ee|ed|ing)?",
          "whatsoever");

  public CopyrightScanner(
      Iterable<String> firstPartyLicenses,
      Iterable<String> thirdPartyLicenses,
      Iterable<String> forbiddenLicenses,
      Iterable<String> firstPartyOwners,
      Iterable<String> thirdPartyOwners,
      Iterable<String> forbiddenOwners,
      Iterable<String> excludePatterns) {
    this(
        firstPartyLicenses,
        thirdPartyLicenses,
        forbiddenLicenses,
        firstPartyOwners,
        thirdPartyOwners,
        forbiddenOwners,
        excludePatterns,
        CONTRACT_WORDS);
  }

  private CopyrightScanner(
      Iterable<String> firstPartyLicenses,
      Iterable<String> thirdPartyLicenses,
      Iterable<String> forbiddenLicenses,
      Iterable<String> firstPartyOwners,
      Iterable<String> thirdPartyOwners,
      Iterable<String> forbiddenOwners,
      Iterable<String> excludePatterns,
      Iterable<String> contractWords) {
    ImmutableList.Builder<Pattern> b = ImmutableList.builder();
    if (firstPartyLicenses != null) {
      for (String license : firstPartyLicenses) {
        b.add(patternizeKnownMatch(license));
      }
    }
    this.firstPartyLicenses = b.build();
    b = ImmutableList.builder();
    if (thirdPartyLicenses != null) {
      for (String license : thirdPartyLicenses) {
        b.add(patternizeKnownMatch(license));
      }
    }
    this.thirdPartyLicenses = b.build();
    b = ImmutableList.builder();
    if (forbiddenLicenses != null) {
      for (String license : forbiddenLicenses) {
        b.add(patternizeKnownMatch(license));
      }
    }
    this.forbiddenLicenses = b.build();
    b = ImmutableList.builder();
    if (firstPartyOwners != null) {
      for (String owner : firstPartyOwners) {
        b.add(patternizeKnownMatch(owner));
      }
    }
    this.firstPartyOwners = b.build();
    b = ImmutableList.builder();
    if (thirdPartyOwners != null) {
      for (String owner : thirdPartyOwners) {
        b.add(patternizeKnownMatch(owner));
      }
    }
    this.thirdPartyOwners = b.build();
    b = ImmutableList.builder();
    if (forbiddenOwners != null) {
      for (String owner : forbiddenOwners) {
        b.add(patternizeKnownMatch(owner));
      }
    }
    this.forbiddenOwners = b.build();
    b = ImmutableList.builder();
    for (String word : contractWords) {
      b.add(patternizeKnownMatch(word));
    }
    this.contractWords = b.build();
    Preconditions.checkArgument(!this.contractWords.isEmpty());
    b = ImmutableList.builder();
    if (excludePatterns != null) {
      for (String pattern : excludePatterns) {
        b.add(Pattern.compile(pattern)); // not transformed because applies to normalized matches
      }
    }
    this.excludePatterns = b.build();
    this.copyright = buildPattern();
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (other == null) {
      return false;
    }
    if (other instanceof CopyrightScanner) {
      CopyrightScanner otherScanner = (CopyrightScanner) other;
      return copyright.equals(otherScanner.copyright);
    }
    return false;
  }

  @Override
  public int hashCode() {
    return copyright.hashCode();
  }

  /**
   * Scans `source` for copyright notices returning found license/author/owner information.
   *
   * @param name Arbitrary string identifying the source. Usually a filename.
   * @param size Hint regarding the expected size of the input source. Use -1 if unknown.
   * @param source The source input stream with line endings indexed for lookup.
   * @return the list of matches found in the input stream -- never null.
   */
  public ImmutableList<Match> findMatches(String name, long size, IndexedLineReader source)
      throws IOException {
    Preconditions.checkNotNull(name);
    Preconditions.checkNotNull(source);

    ImmutableList.Builder<Match> builder = ImmutableList.builder();

    // Accumulates unknown licenses in case no known matches found.
    ArrayList<Match> unknowns = new ArrayList<>();

    // Allocate a character buffer using the size hint.
    int searchLength = size < 1 || size > MAX_SEARCH_LENGTH ? MAX_SEARCH_LENGTH : (int) size;
    char[] content = new char[searchLength > 2 ? searchLength : 2]; // minimum 2 chars required
    CharBuffer cb = CharBuffer.wrap(content);

    // Read the input into the character buffer.
    source.read(cb);
    cb.flip(); // Switch from tracking available space to read into to tracking amount read.

    int numUnknown = 0; // track number of contract words from unknown licenses found
    int numLicenses = 0; // track number of licenses versus owners added to the builder
    int numLicenseGroups = // First 2 or 3 captured groups are licenses. Rest are author/owner.
        firstPartyLicenses.isEmpty() && thirdPartyLicenses.isEmpty() && forbiddenLicenses.isEmpty()
            ? 2
            : 3;

    Matcher matcher = copyright.matcher(cb);
    while (matcher.find()) {
      MatchResult mr = matcher.toMatchResult();
      int numBuilt = 0; // track number of matches added to the builder
      for (int i = 1; i <= mr.groupCount(); i++) { // group 0 is entire match not a specific group
        String license = normalizeLicense(mr.group(i));
        if (license == null || license.trim().isEmpty() || isExcluded(license)) {
          continue;
        }
        String owner = normalizeOwner(license);
        if (isForbiddenLicense(license)) {
          builder.add(
              new Match(
                  PartyType.FORBIDDEN,
                  MatchType.LICENSE,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
          numLicenses++;
        } else if (isThirdPartyLicense(license)) {
          builder.add(
              new Match(
                  PartyType.THIRD_PARTY,
                  MatchType.LICENSE,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
          numLicenses++;
        } else if (isFirstPartyLicense(license)) {
          builder.add(
              new Match(
                  PartyType.FIRST_PARTY,
                  MatchType.LICENSE,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
          numLicenses++;
        } else if (i <= numLicenseGroups) { // first 2 or 3 groups are licenses
          builder.add(
              new Match(
                  PartyType.UNKNOWN, // unknown licenses classified as unknown
                  MatchType.LICENSE,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
          numLicenses++;
        } else if (license.toLowerCase().contains("license")
            || license.toLowerCase().contains("licence")) {
          builder.add(
              new Match(
                  PartyType.UNKNOWN, // unknown licenses classified as unknown
                  MatchType.LICENSE,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
          numLicenses++;
        } else if (isForbiddenOwner(owner)) {
          builder.add(
              new Match(
                  PartyType.FORBIDDEN,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
        } else if (isThirdPartyOwner(owner)) {
          builder.add(
              new Match(
                  PartyType.THIRD_PARTY,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
        } else if (isFirstPartyOwner(owner)) {
          builder.add(
              new Match(
                  PartyType.FIRST_PARTY,
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
        } else { // remainder of groups are owner/author copyrights
          builder.add(
              new Match(
                  PartyType.THIRD_PARTY, // unknown authors classified as third party.
                  normalizeLicense(mr.group()),
                  source.getLineNumber(mr.start(i)),
                  source.getLineNumber(mr.end(i)),
                  mr.start(i),
                  mr.end(i)));
        }
        numBuilt++;
      }
      // If no capture group has content, the entire match is a word from an unknown contract.
      // Don't bother accumulating unknown contract matches after known patterns detected.
      if (numLicenses == 0 && numBuilt == 0 && numUnknown <= MATCH_THRESHOLD) {
        String license = normalizeLicense(mr.group());
        if (license.matches("(?i)no copyright(?:able)?.*")) { // exclude negated match
          continue;
        }
        if (isExcluded(license)) {
          continue;
        }
        if (license.matches( // exclude common implementation comments using the word `by`
            "(?i:required|return|allocated|allowed|generated|provided|raised|understandable"
                + "|used) by .*")) {}
        int startLine = source.getLineNumber(mr.start());
        int endLine = source.getLineNumber(mr.end());
        String owner = normalizeOwner(license);
        if (isForbiddenLicense(license)) {
          builder.add(
              new Match(
                  PartyType.FORBIDDEN,
                  MatchType.LICENSE,
                  license,
                  startLine,
                  endLine,
                  mr.start(),
                  mr.end()));
          numBuilt++;
          continue;
        } else if (isThirdPartyLicense(license)) {
          builder.add(
              new Match(
                  PartyType.THIRD_PARTY,
                  MatchType.LICENSE,
                  license,
                  startLine,
                  endLine,
                  mr.start(),
                  mr.end()));
          numBuilt++;
          continue;
        } else if (isFirstPartyLicense(license)) {
          builder.add(
              new Match(
                  PartyType.FIRST_PARTY,
                  MatchType.LICENSE,
                  license,
                  startLine,
                  endLine,
                  mr.start(),
                  mr.end()));
          numBuilt++;
          continue;
        } else if (isForbiddenOwner(owner)) {
          builder.add(
              new Match(PartyType.FORBIDDEN, license, startLine, endLine, mr.start(), mr.end()));
          numBuilt++;
          continue;
        } else if (isThirdPartyOwner(owner)) {
          builder.add(
              new Match(PartyType.THIRD_PARTY, license, startLine, endLine, mr.start(), mr.end()));
          numBuilt++;
          continue;
        } else if (isFirstPartyOwner(owner)) {
          builder.add(
              new Match(PartyType.FIRST_PARTY, license, startLine, endLine, mr.start(), mr.end()));
          numBuilt++;
          continue;
        }
        Match priorMatch = !unknowns.isEmpty() ? Iterables.getLast(unknowns) : null;
        // If close to an earlier match (within 6 lines or 300 chars), extend the match to include
        // the new word.
        if (priorMatch != null
            && (startLine - priorMatch.endLine < 6 || mr.start() - priorMatch.end < 300)) {
          priorMatch.text = priorMatch.text + "..." + license;
          priorMatch.endLine = endLine;
          priorMatch.end = mr.end();
        } else {
          // Otherwise, create a new match.
          if (numUnknown < MATCH_THRESHOLD) {
            unknowns.add(
                new Match(
                    PartyType.UNKNOWN,
                    MatchType.LICENSE,
                    license,
                    startLine,
                    endLine,
                    mr.start(),
                    mr.end()));
          }
          numUnknown++;
        }
      }
      // Stop the search early if enough known patterns already matched.
      if (numBuilt >= MATCH_THRESHOLD) {
        break;
      }
    }
    // Return unknown contracts only when found and no known patterns matched.
    if (numLicenses == 0) {
      builder.addAll(unknowns);
    }
    return builder.build();
  }

  /**
   * Constructs the search pattern incorporating the known matches into the generic regular
   * expression.
   *
   * <p>The first 2 or 3 match groups correspond to license matches. If the configuration specifies
   * known license patterns (1p, 3p or forbidden), the 1st match group will include these matches.
   *
   * <p>If the configuration specifies no known license patterns, the 1st and 2nd match groups will
   * include matches to the generic license pattern. Otherwise, the 2nd and 3rd match groups will
   * include these.
   *
   * <p>Subsequent match groups are all copyright author/owner matches.
   *
   * <p>The arbitrary contract words expression uses a non-capturing group. If none of the other
   * match groups contain any content, the entire match is treated as an unknown license word.
   */
  private Pattern buildPattern() {
    StringBuilder words = new StringBuilder();
    for (Pattern word : contractWords) {
      if (words.length() > 0) {
        words.append('|');
      }
      words.append(word);
    }

    StringBuilder owners = new StringBuilder();
    owners.append("(?:by");
    owners.append(WS);
    owners.append("{1,msl})?(?:the");
    owners.append(WS);
    owners.append("{1,msl})?("); // owner expression always captured here
    for (Pattern owner : thirdPartyOwners) {
      String s = owner.toString();
      int start = s.startsWith(".*") || s.startsWith(".+") ? 2 : 0;
      int end = s.endsWith(".*") || s.endsWith(".+") ? s.length() - 2 : s.length();
      owners.append(owner.toString().substring(start, end));
      owners.append('|');
    }
    for (Pattern owner : firstPartyOwners) {
      String s = owner.toString();
      int start = s.startsWith(".*") || s.startsWith(".+") ? 2 : 0;
      int end = s.endsWith(".*") || s.endsWith(".+") ? s.length() - 2 : s.length();
      owners.append(owner.toString().substring(start, end));
      owners.append('|');
    }
    for (Pattern owner : forbiddenOwners) {
      String s = owner.toString();
      int start = s.startsWith(".*") || s.startsWith(".+") ? 2 : 0;
      int end = s.endsWith(".*") || s.endsWith(".+") ? s.length() - 2 : s.length();
      owners.append(owner.toString().substring(start, end));
      owners.append('|');
    }
    owners.append("(?:");
    owners.append(NAME);
    owners.append("(?:");
    owners.append(WS);
    owners.append("{1,msl}");
    owners.append(NAME);
    owners.append("){0,mnr}))"); // end of owner capture

    // One of the frequent objections to regular expressions is the objection that long or complex
    // expressions are difficult to read, and they are. Avoid changes to the expressions below. If
    // given a choice between making a change below or adding a few "known owner"/"known license"
    // patterns to the configuration, bias toward configuration.
    //
    // If that is not possible, one of the most difficult tasks when maintaining these expressions
    // is balancing the parentheses and braces at the appropriate parts. The author of the below
    // expression added a System.err.println() statement to output:
    //   pattern.toString().replaceall("([(](?:[?][:])?)", "$1\n").replaceall("[)]", "\n$1")
    // inserting newlines after opening parentheses and before closing parentheses. The output
    // was then fed through an awk script to indent the nested expressions:

    /* awk '
         BEGIN {
           p="";
         }
         $0 ~ /^[)].*$/ {
           p=substr(p,1, length(p)-2);
         }
         {
           print p $0;
         }
         $0 ~ /[(]([?][:])?$/ {
           p=p "  ";
         }
       '
    */
    // From that output, it was possible to see where parentheses balanced and what changes to make
    // to edit the expression correctly. Not for the fainthearted.
    StringBuilder sb = new StringBuilder();

    // Optional known licence capture.
    if (!firstPartyLicenses.isEmpty()
        || !thirdPartyLicenses.isEmpty()
        || !forbiddenLicenses.isEmpty()) {
      sb.append("("); // start of optional 1st captured match group
      sb.append(
          Streams.concat(
                  thirdPartyLicenses.stream(),
                  firstPartyLicenses.stream(),
                  forbiddenLicenses.stream())
              .map(
                  input -> {
                    if (input == null) {
                      return "";
                    }
                    String s = input.toString();
                    int start = s.startsWith(".*") || s.startsWith(".+") ? 2 : 0;
                    int end = s.endsWith(".*") || s.endsWith(".+") ? s.length() - 2 : s.length();
                    return input.toString().substring(start, end);
                  })
              .collect(Collectors.joining("|")));
      sb.append(")|"); // end of optional 1st captured group and | to introduce 2nd captured group.
    }

    // Other license captures. -- ends with License
    sb.append("(?:is"); // not captured -- helps confirm license but interferes with matching 1p,3p
    sb.append(WS);
    sb.append("{1,msl}(?:distributed|provided)");
    sb.append(WS);
    sb.append("{1,msl}under(?:");
    sb.append(WS);
    sb.append("{1,msl}(?:the|this))?");
    sb.append(WS);
    sb.append("{1,msl}((?:"); // start of 1st or 2nd captured match group
    sb.append(NAME);
    sb.append(WS);
    sb.append(
        "{1,msl}){2,mnr}?licen[cs]e))[,.;]{0,3}(?![:])"); // end of 1st or 2nd captured match group

    // Other license captures. -- Line starting with License:
    sb.append("|(?-ms:licen[cs]e:\\s{1,msl}("); // start of the 2nd or 3rd captured match group
    sb.append(NAME);
    sb.append("(?:\\s{1,msl}");
    sb.append(NAME);
    sb.append("){0,mnr})\\n)"); // end of 2nd or 3rd captured match group

    // "Author is" copyright capture.
    sb.append("|\\b(?:(?:the"); // not captured--helps confirm but interferes with 1p, 3p, forbidden
    sb.append(WS);
    sb.append("{1,msl}author");
    sb.append(WS);
    sb.append("{1,msl}of");
    sb.append(WS);
    sb.append("{1,msl}this");
    sb.append(WS);
    sb.append("{1,msl}software");
    sb.append(WS);
    sb.append("{1,msl}is|\\b(?:(?:principal");
    sb.append(WS);
    sb.append("{1,msl})?author:?))");
    sb.append(WS);
    sb.append("{1,msl}");
    sb.append(owners.toString()); // owner pattern includes capture group
    sb.append(")");

    // Copyright+year(s)+owner copyright capture.
    sb.append("|(?:"); // not captureed -- helps confirm but interferes with 1p, 3p, forbidden
    sb.append(WS);
    sb.append("{0,msl}(?:[(]c[)]|&copy;|©)");
    sb.append(WS);
    sb.append("{0,msl})?(?:(?:copy(?:right|left)(?:");
    sb.append(WS);
    sb.append("{1,msl}notice)?(?:");
    sb.append(WS);
    sb.append("{0,msl}(?:[(]c[)]|&copy;|©))?)|(?:[(]c[)]|&copy;|©))");
    sb.append(WS);
    sb.append("{1,msl}(?:");
    sb.append("[\\p{N}]{2,4}(?:"); // year(s)+owner
    sb.append(WSPCT);
    sb.append("{1,msl}(?:and");
    sb.append(WSPCT);
    sb.append("{1,msl})?[\\p{N}]{2,4}){0,mdr}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:present|now))?");
    sb.append(WSPCT);
    sb.append("{1,msl}");
    sb.append(owners.toString()); // owner pattern includes capture group
    sb.append("|"); // owner+year(s)
    sb.append(owners.toString()); // owner pattern includes capture group
    sb.append(WS);
    sb.append("{1,msl}[\\p{N}]{2,4}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:and");
    sb.append(WSPCT);
    sb.append("{1,msl})?[\\p{N}]{2,4}){0,mdr}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:present|now))?");
    sb.append(")(?:(?:portions)?");
    sb.append(WS);
    sb.append("{0,msl}(?:[(]c[)]|&copy;|©)?");
    sb.append(WS);
    sb.append("{1,msl}copy(?:right|left)(?:");
    sb.append(WS);
    sb.append("{0,msl}(?:[(]c[)]|&copy;|©))?");
    sb.append(WS);
    sb.append("{1,msl}(?:");
    sb.append("[\\p{N}]{2,4}(?:"); // year(s)+owner
    sb.append(WSPCT);
    sb.append("{1,msl}(?:and");
    sb.append(WSPCT);
    sb.append("{1,msl})?[\\p{N}]{2,4}){0,mdr}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:present|now))?");
    sb.append(WSPCT);
    sb.append("{1,msl}");
    sb.append(owners.toString()); // owner pattern (repeated) includes capture group
    sb.append("|"); // owner+year(s)
    sb.append(owners.toString()); // owner pattern (repeated) includes capture group
    sb.append(WS);
    sb.append("{1,msl}[\\p{N}]{2,4}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:and");
    sb.append(WSPCT);
    sb.append("{1,msl})?[\\p{N}]{2,4}){0,mdr}(?:"); // allows pre-y2k 2-digit years
    sb.append(WSPCT);
    sb.append("{1,msl}(?:present|now))?");
    sb.append(")){0,5}"); // captures 0 to 5 additional author/owner declarations

    // Detect contract words to detect unknown licenses.
    sb.append("|(?:(?:\\b|\\p{Pi})(?:"); // unknown licenses use non-capturing group
    sb.append(words);
    sb.append(")(?:");
    sb.append(WS);
    sb.append("(?:");
    sb.append(words);
    sb.append(")){0,mnr}(?:\\b|[,.;:\\p{Pf}]))");

    return Pattern.compile(
        sb.toString()
            .replaceAll("[,]mnl[}]", "," + MAX_NAME_LENGTH + "}")
            .replaceAll("[,]msl[}]", "," + MAX_SPACE_LENGTH + "}")
            .replaceAll("[,]mnr[}]", "," + MAX_NAME_REPETITION + "}")
            .replaceAll("[,]mdr[}]", "," + MAX_DATE_REPETITION + "}"),
        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.UNICODE_CASE | Pattern.DOTALL);
  }

  /** Returns true when `owner` matches any known first party owner. */
  private boolean isExcluded(String match) {
    for (Pattern p : excludePatterns) {
      if (p.matcher(match).find()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `owner` matches any known first party owner. */
  private boolean isFirstPartyOwner(String owner) {
    if (owner == null || owner.isEmpty()) {
      return false;
    }
    for (Pattern p : firstPartyOwners) {
      if (p.matcher(owner).matches()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `owner` matches any known forbidden owner. */
  private boolean isForbiddenOwner(String owner) {
    if (owner == null || owner.isEmpty()) {
      return false;
    }
    for (Pattern p : forbiddenOwners) {
      if (p.matcher(owner).matches()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `owner` matches any known third party owner. */
  private boolean isThirdPartyOwner(String owner) {
    if (owner == null || owner.isEmpty()) {
      return false;
    }
    for (Pattern p : thirdPartyOwners) {
      if (p.matcher(owner).matches()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `license` matches any known first party license. */
  private boolean isFirstPartyLicense(String license) {
    for (Pattern p : firstPartyLicenses) {
      if (p.matcher(license).matches()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `license` matches any known forbidden license. */
  private boolean isForbiddenLicense(String license) {
    for (Pattern p : forbiddenLicenses) {
      if (p.matcher(license).matches()) {
        return true;
      }
    }
    return false;
  }

  /** Returns true when `license` matches any known third party license. */
  private boolean isThirdPartyLicense(String license) {
    for (Pattern p : thirdPartyLicenses) {
      if (p.matcher(license).matches()) {
        return true;
      }
    }
    return false;
  }

  /**
   * Converts a known matching pattern written in a simplified regular expression language into a
   * regular expression treating comment characters as whitespace and replacing unlimited wildcard
   * expressions with expressions using a limited set of characters and a limited quantifier.
   */
  private static Pattern patternizeKnownMatch(String match) {
    Preconditions.checkNotNull(match);
    Preconditions.checkArgument(!match.isEmpty(), "Non-empty pattern required.");
    // Disallow capture groups which will interfere with 1p, 3p, or forbidden classification.
    Preconditions.checkArgument(
        !match.matches("(?:^|.*[^\\[])[(][^?](?:[^:].*|$)"),
        "Capturing group found in /" + match + "/. Use non-capturing (?:...) instead of (...).");
    // Disallow spaces inside character classes because they will get replaced.
    Preconditions.checkArgument(
        !match.matches(".*\\[[^]]*\\s[]].*"),
        "Character class with space in /" + match + "/. Use (?: |...) instead of space in [...].");
    // Replace unlimited "any char" wildcards that can cost too much backtracking with patterns that
    // match a smaller subset of characters with more limited quantifiers.
    //
    // Replace any sequence of whitespace with a regular expression to match any non-empty sequence
    // of whitespace or comment characters.
    String prefix = "";
    if (match.startsWith(".*")) {
      prefix = ".*";
    } else if (match.startsWith(".+")) {
      prefix = ".*";
    }
    String suffix = "";
    if (match.endsWith(".*")) {
      suffix = ".*";
    } else if (match.endsWith(".+")) {
      suffix = ".*";
    }
    return Pattern.compile(
        prefix
            + match
                .substring(prefix.length(), match.length() - suffix.length())
                .replaceAll(
                    "[.][*]",
                    ("(?: "
                            + ANY_CHAR
                            + "{1,"
                            + MAX_NAME_LENGTH
                            + "}){0,"
                            + MAX_NAME_REPETITION
                            + "}")
                        .replace("\\", "\\\\"))
                .replaceAll(
                    "[.][+]",
                    ("(?: "
                            + ANY_CHAR
                            + "{1,"
                            + MAX_NAME_LENGTH
                            + "}){1,"
                            + MAX_NAME_REPETITION
                            + "}")
                        .replace("\\", "\\\\"))
                .replaceAll("\\s+[?]", WS.replace("\\", "\\\\") + "{0," + MAX_SPACE_LENGTH + "}")
                .replaceAll("\\s+", WS.replace("\\", "\\\\") + "{1," + MAX_SPACE_LENGTH + "}")
            + suffix,
        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.UNICODE_CASE | Pattern.DOTALL);
  }

  /**
   * Replaces sequences of whitespace and comment characters with a single space preserving URLs,
   * which often contain `/` or `#` as non-comment characters.
   */
  private static String normalizeLicense(String match) {
    if (match == null) {
      return null;
    }
    StringBuilder sb = new StringBuilder();
    Matcher m = Pattern.compile(URL).matcher(match);
    int nextIndex = 0;
    while (m.find()) {
      int start = m.start();
      if (nextIndex < start) {
        sb.append(match.substring(nextIndex, start).replaceAll(WS + "+", " "));
      }
      sb.append(m.group());
      nextIndex = m.end();
    }
    if (nextIndex < match.length()) {
      sb.append(match.substring(nextIndex).replaceAll(WS + "+", " "));
    }
    return sb.toString().trim();
  }

  /**
   * Strips common non-author/owner suffixes that get picked up unintentionally from previously
   * normalized license with sequences of whitespace and comment characters replaced with a single
   * space preserving URLS, which often contain `/` or `#` as non-comment characters.
   *
   * <p>The generic license pattern always ends by matching the word `license` or stops at the end
   * of the line so it does not pick up spurious additional text. The generic owner pattern does not
   * end in a specific word so it often includes spurious additional words like #ifdef or #ifndef,
   * which interfere when comparing the match against known author/owner patterns. This method
   * strips the most common non-author/owner words from the end of the match.
   */
  private static String normalizeOwner(String license) {
    if (license == null) {
      return null;
    }
    return license
        .split(
            "(?i)[ ](?:all rights|(?:the|this) [^ ]+(?: [^ ]+){0,2} (?:is|assumes|may)"
                + "|permission|copyright|version \\p{N}|for conditions|include |include$"
                + "|modification|however|open source license|please (?:use|read)|libname"
                + "|if defined|usage|this is free|added|generic|redistribution|ifdef|ifndef"
                + "|for (?:more|terms)|copying and|you (?:may|can)|released under|see the"
                + "|full source|freedom to use|this program and|distributed|https?|unit ?test"
                + "|import|static|by obtaining|by using|by copying|example|namespace|config\\b"
                + "|public (?:static|final|class)|package (?:org|com)|[^ ]+ is hereby)")[0];
  }

  /** Identifies the relevant party as 1p, 3p, forbidden, or unknown. */
  public enum PartyType {
    FIRST_PARTY,
    THIRD_PARTY,
    UNKNOWN,
    FORBIDDEN,
  }

  /** Identifies whether text matched by author/owner pattern or by license pattern. */
  public enum MatchType {
    AUTHOR_OWNER,
    LICENSE,
  }

  /**
   * Describes a copyright author/owner or license `text` match found in the input stream.
   *
   * <p>Identifies the relevant party as `FIRST_PARTY`, `THIRD_PARTY`, `FORBIDDEN`, or `UNKNOWN`.
   *
   * <p>Identifies the match as `AUTHOR_OWNER` or `LICENSE`.
   *
   * <p>Includes a normalized version of the matched text including where it was found in the file.
   */
  public static class Match {
    /** Classifies relevant party as 1p, 3p, forbidden, or unknown. */
    public PartyType partyType;
    /** Classifies match as author/owner or as license. */
    public MatchType matchType;
    /** Matched text with spaces and comment characters replaced by a single space. */
    public String text;
    /** The line number in the file where the match starts. */
    public int startLine;
    /** The line number in the file where the match ends. */
    public int endLine;
    /** The character offset into the file where the match starts. */
    public int start;
    /** The character offset into the file where the match ends. */
    public int end;

    public Match(PartyType partyType, String text, int startLine, int endLine, int start, int end) {
      this(partyType, MatchType.AUTHOR_OWNER, text, startLine, endLine, start, end);
    }

    public Match(
        PartyType partyType,
        MatchType matchType,
        String text,
        int startLine,
        int endLine,
        int start,
        int end) {
      this.partyType = partyType;
      this.matchType = matchType;
      this.text = text;
      this.startLine = startLine;
      this.endLine = endLine;
      this.start = start;
      this.end = end;
    }
  }
}
