// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// See README in this directory for information on how this code is organized.

import 'dart:core' hide RegExp;
import 'dart:io' as system;
import 'dart:math' as math;

import 'package:args/args.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:crypto/crypto.dart' as crypto;
import 'package:path/path.dart' as path;

import 'filesystem.dart' as fs;
import 'licenses.dart';
import 'paths.dart';
import 'patterns.dart';
import 'regexp_debug.dart';

abstract class _RepositoryEntry implements Comparable<_RepositoryEntry> {
  _RepositoryEntry(this.parent, this.io);
  final _RepositoryDirectory? parent;
  final fs.IoNode io;
  String get name => io.name;

  @override
  int compareTo(_RepositoryEntry other) => toString().compareTo(other.toString());

  @override
  String toString() => io.fullName;
}

abstract class _RepositoryFile extends _RepositoryEntry {
  _RepositoryFile(_RepositoryDirectory super.parent, fs.File super.io);

  fs.File get ioFile => super.io as fs.File;
}

abstract class _RepositoryLicensedFile extends _RepositoryFile {
  _RepositoryLicensedFile(super.parent, super.io);

  // Returns the License that is found inside this file.
  //
  // Used when one file says it is covered by the license of another file.
  License extractInternalLicense() {
    throw 'tried to extract a license from $this but it does not contain text';
  }

  // Creates the mapping from the file to its licenses.
  //
  // Subclasses implement things like applying licenses found within the file
  // itself, applying licenses that point to other files, etc.
  //
  // The assignments are later grouped when generating the output, see
  // groupLicenses in licenses.dart.
  Iterable<Assignment> assignLicenses() {
    final List<License> licenses = parent!.nearestLicensesFor(name);
    if (licenses.isEmpty) {
      throw 'file has no detectable license and no in-scope default license file';
    }
    return licenses.map((License license) => license.assignLicenses(io.fullName, parent!));
  }
}

class _RepositorySourceFile extends _RepositoryLicensedFile {
  _RepositorySourceFile(super.parent, fs.TextFile super.io) : _contents = _readFile(io);

  fs.TextFile get ioTextFile => super.io as fs.TextFile;

  final String _contents;

  static String _readFile(fs.TextFile ioTextFile) {
    late String contents;
    try {
      contents = ioTextFile.readString();
    } on FormatException {
      throw 'non-UTF8 data in $ioTextFile';
    }
    return contents;
  }

  List<License>? _internalLicenses;

  @override
  License extractInternalLicense() {
    _internalLicenses ??= determineLicensesFor(_contents, name, parent, origin: io.fullName);
    if (_internalLicenses == null || _internalLicenses!.isEmpty) {
      throw 'tried to extract a license from $this but there is nothing here';
    }
    if (_internalLicenses!.length > 1) {
      throw 'tried to extract a license from $this but there are multiple licenses in this file';
    }
    return _internalLicenses!.single;
  }

  @override
  Iterable<Assignment> assignLicenses() {
    _internalLicenses ??= determineLicensesFor(_contents, name, parent, origin: io.fullName);
    final List<License>? licenses = _internalLicenses;
    if (licenses != null && licenses.isNotEmpty) {
      return licenses.map((License license) => license.assignLicenses(io.fullName, parent!));
    }
    return super.assignLicenses();
  }
}

class _RepositoryBinaryFile extends _RepositoryLicensedFile {
  _RepositoryBinaryFile(super.parent, super.io);

  @override
  Iterable<Assignment> assignLicenses() {
    final List<License> licenses = parent!.nearestLicensesFor(name);
    if (licenses.isEmpty) {
      throw 'no license file found in scope for ${io.fullName}';
    }
    return licenses.map((License license) => license.assignLicenses(io.fullName, parent!));
  }
}

// LICENSES

abstract class _RepositoryLicenseFile extends _RepositoryFile {
  _RepositoryLicenseFile(super.parent, fs.TextFile super.io);

  // returns any licenses that apply specifically to the file named "name"
  List<License> licensesFor(String name) => licenses;

  // returns the license that applies to files looking for a license of the given type
  License? licenseOfType(LicenseType type);

  // returns the license that applies to files looking for a license of the given name
  License? licenseWithName(String name);

  License? get defaultLicense;
  List<License> get licenses;
}

abstract class _RepositorySingleLicenseFile extends _RepositoryLicenseFile {
  _RepositorySingleLicenseFile(super.parent, super.io, this.license);

  final License license;

  @override
  License? licenseWithName(String name) {
    if (this.name == name) {
      return license;
    }
    return null;
  }

  @override
  License? licenseOfType(LicenseType type) {
    assert(type != LicenseType.unknown);
    if (type == license.type) {
      return license;
    }
    return null;
  }

  @override
  License get defaultLicense => license;

  @override
  List<License> get licenses => <License>[license];
}

class _RepositoryGeneralSingleLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryGeneralSingleLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static License _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    int start = 0;
    Match? match;
    while ((match = licenseHeaders.matchAsPrefix(body, start)) != null) {
      assert(match!.end > start);
      start = match!.end; // https://github.com/dart-lang/sdk/issues/50264
    }
    return License.fromBodyAndName(body.substring(start), io.name, origin: io.fullName);
  }
}

// Avoid using this unless the license file has multiple licenses in a weird mishmash.
// For example, the RapidJSON license which mixes BSD and MIT in somewhat confusing ways
// (e.g. having the copyright for one above the terms for the other and so on).
class _RepositoryOpaqueLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryOpaqueLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, License.unique(io.readString(), LicenseType.unknown, origin: io.fullName, yesWeKnowWhatItLooksLikeButItIsNot: true));
}

class _RepositoryReadmeIjgFile extends _RepositorySingleLicenseFile {
  _RepositoryReadmeIjgFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  // The message we are required to include in our output.
  //
  // We include it by just including the whole license.
  static const String _message = 'this software is based in part on the work of the Independent JPEG Group';

  // The license text that says we should output _message.
  //
  // We inject _message into it, munged such that each space character can also
  // match a newline, so that if the license wraps the text, it still matches.
  static final RegExp _pattern = RegExp(
    r'Permission is hereby granted to use, copy, modify, and distribute this\n'
    r'software \(or portions thereof\) for any purpose, without fee, subject to these\n'
    r'conditions:\n'
    r'\(1\) If any part of the source code for this software is distributed, then this\n'
    r'README file must be included, with this copyright and no-warranty notice\n'
    r'unaltered; and any additions, deletions, or changes to the original files\n'
    r'must be clearly indicated in accompanying documentation\.\n'
    r'\(2\) If only executable code is distributed, then the accompanying\n'
    r'documentation must state that "' '${_message.replaceAll(" ", "[ \n]+")}' r'"\.\n'
    r'\(3\) Permission for use of this software is granted only if the user accepts\n'
    r'full responsibility for any undesirable consequences; the authors accept\n'
    r'NO LIABILITY for damages of any kind\.\n',
  );

  static License _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    if (!body.contains(_pattern)) {
      throw 'unexpected contents in IJG README';
    }
    return License.message(body, LicenseType.ijg, origin: io.fullName);
  }

  @override
  License? licenseWithName(String name) {
    if (this.name == name) {
      return license;
    }
    return null;
  }
}

class _RepositoryMpl2File extends _RepositorySingleLicenseFile {
  _RepositoryMpl2File(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static License _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    if (!body.startsWith('Mozilla Public License Version 2.0')) {
      throw 'unexpected contents in file supposedly containing MPL';
    }
    return License.mozilla(body, origin: io.fullName);
  }

  @override
  License? licenseWithName(String name) {
    if (this.name == 'http://mozilla.org/MPL/2.0/') {
      return license;
    }
    return null;
  }
}

class _RepositoryDartLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryDartLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static final RegExp _pattern = RegExp(
    r'(Copyright (?:.|\n)+)$',
  );

  static License _parseLicense(fs.TextFile io) {
    final Match? match = _pattern.firstMatch(io.readString());
    if (match == null || match.groupCount != 1) {
      throw 'unexpected Dart license file contents';
    }
    return License.template(match.group(1)!, LicenseType.bsd, origin: io.fullName);
  }
}

class _RepositoryLibPngLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryLibPngLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, License.message(io.readString(), LicenseType.libpng, origin: io.fullName)) {
    _verifyLicense(io);
  }

  static void _verifyLicense(fs.TextFile io) {
    final String contents = io.readString();
    if (!contents.contains(RegExp('COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:?')) ||
        !contents.contains('png')) {
      throw 'unexpected libpng license file contents:\n----8<----\n$contents\n----<8----';
    }
  }
}

class _RepositoryLibJpegTurboLicenseFile extends _RepositoryLicenseFile {
  _RepositoryLibJpegTurboLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io) {
    _parseLicense(io);
  }

  static final RegExp _pattern = RegExp(
    r'libjpeg-turbo is covered by three compatible BSD-style open source licenses:\n'
    r'\n'
    r'- The IJG \(Independent JPEG Group\) License, which is listed in\n'
    r'  \[README\.ijg\]\(README\.ijg\)\n'
    r'\n'
    r'  This license applies to the libjpeg API library and associated programs\n'
    r'  \(any code inherited from libjpeg, and any modifications to that code\.\)\n'
    r'\n'
    r'- The Modified \(3-clause\) BSD License, which is listed in\n'
    r'  \[turbojpeg\.c\]\(turbojpeg\.c\)\n'
    r'\n'
    r'  This license covers the TurboJPEG API library and associated programs\.\n'
    r'\n'
    r'- The zlib License, which is listed in \[simd/jsimdext\.inc\]\(simd/jsimdext\.inc\)\n'
    r'\n'
    r'  This license is a subset of the other two, and it covers the libjpeg-turbo\n'
    r'  SIMD extensions\.\n'
  );

  static void _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    if (!body.contains(_pattern)) {
      throw 'unexpected contents in libjpeg-turbo LICENSE';
    }
  }

  @override
  License? licenseWithName(String name) {
    return null;
  }

  @override
  License? licenseOfType(LicenseType type) {
    return null;
  }

  @override
  License? get defaultLicense => null;

  List<License>? _licenses;

  @override
  List<License> get licenses {
    if (_licenses == null) {
      final _RepositoryLicenseFile readme = parent!.getChildByName('README.ijg') as _RepositoryReadmeIjgFile;
      final _RepositorySourceFile main = parent!.getChildByName('turbojpeg.c') as _RepositorySourceFile;
      final _RepositoryDirectory simd = parent!.getChildByName('simd') as _RepositoryDirectory;
      final _RepositorySourceFile zlib = simd.getChildByName('jsimdext.inc') as _RepositorySourceFile;
      _licenses = <License>[];
      _licenses!.addAll(readme.licenses);
      _licenses!.add(main.extractInternalLicense());
      _licenses!.add(zlib.extractInternalLicense());
    }
    return _licenses!;
  }
}

class _RepositoryFreetypeLicenseFile extends _RepositoryLicenseFile {
  _RepositoryFreetypeLicenseFile(super.parent, super.io)
    : _target = _parseLicense(io);

  static final RegExp _pattern = RegExp(
    r'FREETYPE LICENSES\n'
    r'-----------------\n'
    r'\n'
    r'The FreeType  2 font  engine is  copyrighted work  and cannot  be used\n'
    r'legally without  a software  license\.  In order  to make  this project\n'
    r'usable to  a vast majority of  developers, we distribute it  under two\n'
    r'mutually exclusive open-source licenses\.\n'
    r'\n'
    r'This means that \*you\* must choose  \*one\* of the two licenses described\n'
    r'below, then obey all its terms and conditions when using FreeType 2 in\n'
    r'any of your projects or products\.\n'
    r'\n'
    r'  - The FreeType License,  found in the file  `docs/(FTL\.TXT)`, which is\n'
    r'    similar to the  original BSD license \*with\*  an advertising clause\n'
    r'    that forces  you to explicitly  cite the FreeType project  in your\n'
    r"    product's  documentation\.  All  details are  in the  license file\.\n"
    r"    This license is suited to products which don't use the GNU General\n"
    r'    Public License\.\n'
    r'\n'
    r'    Note that  this license  is compatible to  the GNU  General Public\n'
    r'    License version 3, but not version 2\.\n'
    r'\n'
    r'  - The   GNU   General   Public   License   version   2,   found   in\n'
    r'    `docs/GPLv2\.TXT`  \(any  later  version  can  be  used  also\),  for\n'
    r'    programs  which  already  use  the  GPL\.  Note  that  the  FTL  is\n'
    r'    incompatible with GPLv2 due to its advertisement clause\.\n'
    r'\n'
    r'The contributed  BDF and PCF  drivers come  with a license  similar to\n'
    r'that  of the  X Window  System\.   It is  compatible to  the above  two\n'
    r'licenses \(see files `src/bdf/README`  and `src/pcf/README`\)\.  The same\n'
    r'holds   for   the   source    code   files   `src/base/fthash\.c`   and\n'
    r'`include/freetype/internal/fthash\.h`; they wer part  of the BDF driver\n'
    r'in earlier FreeType versions\.\n'
    r'\n'
    r'The gzip  module uses the  zlib license \(see  `src/gzip/zlib\.h`\) which\n'
    r'too is compatible to the above two licenses\.\n'
    r'\n'
    r'The  MD5 checksum  support  \(only used  for  debugging in  development\n'
    r'builds\) is in the public domain\.\n'
    r'\n*'
    r'--- end of LICENSE\.TXT ---\n*$'
  );

  static String _parseLicense(fs.TextFile io) {
    final Match? match = _pattern.firstMatch(io.readString());
    if (match == null || match.groupCount != 1) {
      throw 'unexpected Freetype license file contents';
    }
    return match.group(1)!;
  }

  final String _target;
  List<License>? _targetLicense;

  void _warmCache() {
    if (parent != null && _targetLicense == null) {
      final License? license = parent!.nearestLicenseWithName(_target);
      if (license == null) {
        throw 'Could not find license in Freetype directory. Make sure $_target is not excluded from consideration.';
      }
      _targetLicense = <License>[license];
    }
  }

  @override
  License? licenseOfType(LicenseType type) => null;

  @override
  License? licenseWithName(String name) => null;

  @override
  License get defaultLicense {
    _warmCache();
    return _targetLicense!.single;
  }

  @override
  List<License> get licenses {
    _warmCache();
    return _targetLicense ?? const <License>[];
  }
}

class _RepositoryIcuLicenseFile extends _RepositorySingleLicenseFile {
  factory _RepositoryIcuLicenseFile(_RepositoryDirectory parent, fs.TextFile io) {
    final Match? match = _pattern.firstMatch(_fixup(io.readString()));
    if (match == null) {
      throw 'could not parse ICU license file';
    }
    const int groupCount = 22;
    assert(match.groupCount == groupCount, 'ICU: expected $groupCount groups, but got ${match.groupCount}');
    const int timeZoneGroup = 18;
    if (match.group(timeZoneGroup)!.contains(copyrightMentionPattern)) {
      throw 'ICU: unexpected copyright in time zone database group\n:${match.group(timeZoneGroup)}';
    }
    if (!match.group(timeZoneGroup)!.contains('7.  Database Ownership')) {
      throw 'ICU: unexpected text in time zone database group\n:${match.group(timeZoneGroup)}';
    }
    const int gplGroup1 = 20;
    const int gplGroup2 = 21;
    if (!match.group(gplGroup1)!.contains(gplExceptionExplanation1) || !match.group(gplGroup2)!.contains(gplExceptionExplanation2)) {
      throw 'ICU: did not find GPL exception in GPL-licensed files';
    }
    const Set<int> skippedGroups = <int>{ timeZoneGroup, gplGroup1, gplGroup2 };
    return _RepositoryIcuLicenseFile._(
      parent,
      io,
      License.template(match.group(2)!, LicenseType.bsd, origin: io.fullName),
      License.fromMultipleBlocks(
        match.groups(
          Iterable<int>
            .generate(groupCount, (int index) => index + 1)
            .where((int index) => !skippedGroups.contains(index))
            .toList()
        ).cast<String>(),
        LicenseType.icu,
        origin: io.fullName,
        yesWeKnowWhatItLooksLikeButItIsNot: true,
      ),
    );
  }

  _RepositoryIcuLicenseFile._(_RepositoryDirectory parent, fs.TextFile io, this.template, License license)
    : super(parent, io, license);

  static final RegExp _pattern = RegExp(
    r'^(UNICODE, INC\. LICENSE AGREEMENT - DATA FILES AND SOFTWARE\n+' // group
    r'See Terms of Use (?:.|\n)+?'
    r'COPYRIGHT AND PERMISSION NOTICE\n+'
    r'Copyright.+\n'
    r'Distributed under the Terms of Use in .+\n+'
    r')(Permission is hereby granted(?:.|\n)+?)' // template group
    r'\n+-+\n+'
    r'(Third-Party Software Licenses\n+' // group
    r'This section contains third-party software notices and/or additional\n'
    r'terms for licensed third-party software components included within ICU\n'
    r'libraries\.\n+)'
    r'-+\n+'
    r'(ICU License - ICU 1\.8\.1 to ICU 57.1[ \n]+?' // group
    r'COPYRIGHT AND PERMISSION NOTICE\n+'
    r'Copyright (?:.|\n)+?)\n+'
    r'-+\n+'
    r'(Chinese/Japanese Word Break Dictionary Data \(cjdict\.txt\)\n+)' // group
    r'( #     The Google Chrome software developed by Google is licensed under\n?' // group
    r' # the BSD license\. Other software included in this distribution is\n?'
    r' # provided under other licenses, as set forth below\.\n'
    r' #\n'
    r' #  The BSD License\n'
    r' #  http://opensource\.org/licenses/bsd-license\.php\n'
    r' # +Copyright(?:.|\n)+?)\n'
    r' #\n'
    r' #\n'
    r'( #  The word list in cjdict.txt are generated by combining three word lists\n?' // group
    r' # listed below with further processing for compound word breaking\. The\n?'
    r' # frequency is generated with an iterative training against Google web\n?'
    r' # corpora\.\n'
    r' #\n' // if this section is taken out, make sure to remove the cjdict.txt exclusion in paths.dart
    r' #  \* Libtabe \(Chinese\)\n'
    r' #    - https://sourceforge\.net/project/\?group_id=1519\n'
    r' #    - Its license terms and conditions are shown below\.\n'
    r' #\n'
    r' #  \* IPADIC \(Japanese\)\n'
    r' #    - http://chasen\.aist-nara\.ac\.jp/chasen/distribution\.html\n'
    r' #    - Its license terms and conditions are shown below\.\n'
    r' #\n)'
    r' #  ---------COPYING\.libtabe ---- BEGIN--------------------\n'
    r' #\n'
    r' # +/\*\n'
    r'( # +\* Copyright (?:.|\n)+?)\n' // group
    r' # +\*/\n'
    r' #\n'
    r' # +/\*\n'
    r'( # +\* Copyright (?:.|\n)+?)\n' // group
    r' # +\*/\n'
    r' #\n'
    r'( # +Copyright (?:.|\n)+?)\n' // group
    r' #\n'
    r' # +---------------COPYING\.libtabe-----END--------------------------------\n'
    r' #\n'
    r' #\n'
    r' # +---------------COPYING\.ipadic-----BEGIN-------------------------------\n'
    r' #\n'
    r'( # +Copyright (?:.|\n)+?)\n' // group
    r' #\n'
    r' # +---------------COPYING\.ipadic-----END----------------------------------\n+'
    r'-+\n+'
    r'(Lao Word Break Dictionary Data \(laodict\.txt\)\n)' // group
    r'\n' // if this section is taken out, make sure to remove the laodict.txt exclusion in paths.dart
    r'( # +Copyright(?:.|\n)+?)' // group
    r'( # +This file is derived(?:.|\n)+?)\n'
    r'\n'
    r'-+\n'
    r'\n'
    r'(Burmese Word Break Dictionary Data \(burmesedict\.txt\)\n)' // group
    r'\n' // if this section is taken out, make sure to remove the burmesedict.txt exclusion in paths.dart
    r'( # +Copyright(?:.|\n)+?)\n' // group
    r' # +-+\n'
    r'( # +Copyright(?:.|\n)+?)\n' // group
    r' # +-+\n+'
    r'-+\n+'
    r'( *Time Zone Database\n'
    r'(?:.|\n)+)\n' // group (not really a license -- excluded)
    r'\n'
    r'-+\n'
    r'\n'
    r'(Google double-conversion\n' // group
    r'\n'
    r'Copyright(?:.|\n)+)\n'
    r'\n'
    r'-+\n'
    r'\n'
    r'(File: aclocal\.m4 \(only for ICU4C\)\n' // group (excluded)
    r'Section: pkg\.m4 - Macros to locate and utilise pkg-config\.\n+'
    r'Copyright (?:.|\n)+?)\n'
    r'\n'
    r'-+\n'
    r'\n'
    r'(File: config\.guess \(only for ICU4C\)\n+' // group (excluded)
    r'This file is free software(?:.|\n)+?)\n'
    r'\n'
    r'-+\n'
    r'\n'
    r'(File: install-sh \(only for ICU4C\)\n+' // group
    r'Copyright(?:.|\n)+)',
  );

  static const String gplExceptionExplanation1 =
    'As a special exception to the GNU General Public License, if you\n'
    'distribute this file as part of a program that contains a\n'
    'configuration script generated by Autoconf, you may include it under\n'
    'the same distribution terms that you use for the rest of that\n'
    'program.\n'
    '\n'
    '\n'
    '(The condition for the exception is fulfilled because\n'
    'ICU4C includes a configuration script generated by Autoconf,\n'
    'namely the `configure` script.)';

  static const String gplExceptionExplanation2 =
    'As a special exception to the GNU General Public License, if you\n'
    'distribute this file as part of a program that contains a\n'
    'configuration script generated by Autoconf, you may include it under\n'
    'the same distribution terms that you use for the rest of that\n'
    'program.  This Exception is an additional permission under section 7\n'
    'of the GNU General Public License, version 3 ("GPLv3").\n'
    '\n'
    '\n'
    '(The condition for the exception is fulfilled because\n'
    'ICU4C includes a configuration script generated by Autoconf,\n'
    'namely the `configure` script.)';

  // Fixes an error in the license's formatting that our reformatter wouldn't be
  // able to figure out on its own and which would otherwise completely mess up
  // the reformatting of this license file.
  static String _fixup(String license) {
    return license.replaceAll(
      ' #       *                    Sinica. All rights reserved.',
      ' #   *                    Sinica. All rights reserved.',
    );
  }

  final License template;

  @override
  License? licenseOfType(LicenseType type) {
    if (type == LicenseType.defaultTemplate) {
      return template;
    }
    return super.licenseOfType(type);
  }
}

Iterable<List<int>> splitIntList(List<int> data, int boundary) sync* {
  int index = 0;
  List<int> getOne() {
    final int start = index;
    int end = index;
    while ((end < data.length) && (data[end] != boundary)) {
      end += 1;
    }
    end += 1;
    index = end;
    return data.sublist(start, end).toList();
  }

  while (index < data.length) {
    yield getOne();
  }
}

class _RepositoryCxxStlDualLicenseFile extends _RepositoryLicenseFile {
  _RepositoryCxxStlDualLicenseFile(super.parent, super.io)
    : _licenses = _parseLicenses(io);

  static final RegExp _pattern = RegExp(
    r'^'
    r'==============================================================================\n'
    r'The LLVM Project is under the Apache License v2\.0 with LLVM Exceptions:\n'
    r'==============================================================================\n'
    r'\n('
    r' *Apache License\n'
    r' *Version 2.0, January 2004\n'
    r' *http://www.apache.org/licenses/\n'
    r'\n'
    r'.+?)\n+'
    r'---- LLVM Exceptions to the Apache 2.0 License ----'
    r'.+?'
    r'==============================================================================\n'
    r'Software from third parties included in the LLVM Project:\n'
    r'==============================================================================\n'
    r'The LLVM Project contains third party software which is under different license\n'
    r'terms\. All such code will be identified clearly using at least one of two\n'
    r'mechanisms:\n'
    r'1\) It will be in a separate directory tree with its own `LICENSE\.txt` or\n'
    r' *`LICENSE` file at the top containing the specific license and restrictions\n'
    r' *which apply to that software, or\n'
    r'2\) It will contain specific license and restriction terms at the top of every\n'
    r' *file\.\n'
    r'\n'
    r'==============================================================================\n'
    r'Legacy LLVM License \(https://llvm\.org/docs/DeveloperPolicy\.html#legacy\):\n'
    r'==============================================================================\n'
    r'\n'
    r'The libc\+\+(?:abi)? library is dual licensed under both the University of Illinois\n'
    r'"BSD-Like" license and the MIT license\. *As a user of this code you may choose\n'
    r'to use it under either license\. *As a contributor, you agree to allow your code\n'
    r'to be used under both\.\n'
    r'\n'
    r'Full text of the relevant licenses is included below\.\n'
    r'\n'
    r'==============================================================================\n'
    r'\n'
    r'University of Illinois/NCSA\n'
    r'Open Source License\n'
    r'\n'
    r'(Copyright \(c\) 2009-2019 by the contributors listed in CREDITS\.TXT\n'
    r'\n'
    r'All rights reserved\.\n'
    r'\n'
    r'Developed by:\n'
    r'\n'
    r' *LLVM Team\n'
    r'\n'
    r' *University of Illinois at Urbana-Champaign\n'
    r'\n'
    r' *http://llvm\.org\n'
    r'\n'
    r'Permission is hereby granted, free of charge, to any person obtaining a copy of\n'
    r'this software and associated documentation files \(the "Software"\), to deal with\n'
    r'the Software without restriction, including without limitation the rights to\n'
    r'use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n'
    r'of the Software, and to permit persons to whom the Software is furnished to do\n'
    r'so, subject to the following conditions:\n'
    r'\n'
    r' *\* Redistributions of source code must retain the above copyright notice,\n'
    r' *this list of conditions and the following disclaimers\.\n'
    r'\n'
    r' *\* Redistributions in binary form must reproduce the above copyright notice,\n'
    r' *this list of conditions and the following disclaimers in the\n'
    r' *documentation and/or other materials provided with the distribution\.\n'
    r'\n'
    r' *\* Neither the names of the LLVM Team, University of Illinois at\n'
    r' *Urbana-Champaign, nor the names of its contributors may be used to\n'
    r' *endorse or promote products derived from this Software without specific\n'
    r' *prior written permission\.\n'
    r'\n'
    r'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n'
    r'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n'
    r'FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\.  IN NO EVENT SHALL THE\n'
    r'CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n'
    r'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n'
    r'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\n'
    r'SOFTWARE\.)\n*'
    r'==============================================================================\n*'
    r'(Copyright \(c\) 2009-2014 by the contributors listed in CREDITS\.TXT\n'
    r'\n'
    r'Permission is hereby granted, free of charge, to any person obtaining a copy\n'
    r'of this software and associated documentation files \(the "Software"\), to deal\n'
    r'in the Software without restriction, including without limitation the rights\n'
    r'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n'
    r'copies of the Software, and to permit persons to whom the Software is\n'
    r'furnished to do so, subject to the following conditions:\n'
    r'\n'
    r'The above copyright notice and this permission notice shall be included in\n'
    r'all copies or substantial portions of the Software\.\n'
    r'\n'
    r'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n'
    r'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n'
    r'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\. IN NO EVENT SHALL THE\n'
    r'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n'
    r'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n'
    r'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n'
    r'THE SOFTWARE\.)\n*'
    r'$',
    dotAll: true,
  );

  static List<License> _parseLicenses(fs.TextFile io) {
    final Match? match = _pattern.firstMatch(io.readString());
    if (match == null) {
      throw 'unexpected license file contents';
    }
    if (match.groupCount != 3) {
      throw 'internal error; match count inconsistency\nRemainder:[[${match.input.substring(match.end)}]]';
    }
    return <License>[
      // License.fromBodyAndType(match.group(1), LicenseType.apache), // the exception says we can ignore this
      License.fromBodyAndType(match.group(2)!, LicenseType.bsd, origin: io.fullName),
      License.fromBodyAndType(match.group(3)!, LicenseType.mit, origin: io.fullName),
    ];
  }

  final List<License> _licenses;

  @override
  License licenseOfType(LicenseType type) {
    throw 'tried to look up a dual-license license by type ("$type")';
  }

  @override
  License licenseWithName(String name) {
    throw 'tried to look up a dual-license license by name ("$name")';
  }

  @override
  License get defaultLicense => _licenses[0];

  @override
  List<License> get licenses => _licenses;
}

class _RepositoryKhronosLicenseFile extends _RepositoryLicenseFile {
  _RepositoryKhronosLicenseFile(super.parent, super.io)
    : _licenses = _parseLicenses(io);

  static final RegExp _pattern = RegExp(
    r'^(Copyright .+?)\n'
    r'SGI FREE SOFTWARE LICENSE B[^\n]+\n\n'
    r'(Copyright .+?)$',
    dotAll: true,
  );

  static List<License> _parseLicenses(fs.TextFile io) {
    final Match? match = _pattern.firstMatch(io.readString());
    if (match == null || match.groupCount != 2) {
      throw 'unexpected Khronos license file contents';
    }
    return <License>[
      License.fromBodyAndType(match.group(1)!, LicenseType.mit, origin: io.fullName),
      License.fromBodyAndType(match.group(2)!, LicenseType.mit, origin: io.fullName),
    ];
  }

  final List<License> _licenses;

  @override
  License licenseOfType(LicenseType type) {
    throw 'tried to look up a combination license by type ("$type")';
  }

  @override
  License licenseWithName(String name) {
    throw 'tried to look up a combination license by name ("$name")';
  }

  @override
  License get defaultLicense {
    throw 'there is no default Khronos license';
  }

  @override
  List<License> get licenses => _licenses;
}

/// The BoringSSL license file.
///
/// This file contains a bunch of different licenses, but other files
/// refer to it as if it was a monolithic license so we sort of have
/// to treat the whole thing as a MultiLicense.
class _RepositoryOpenSSLLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryOpenSSLLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static final RegExp _pattern = RegExp(
    // advice is to skip the first 27 lines of this file in the LICENSE file
    r'^BoringSSL is a fork of OpenSSL. As such, .+?'
    r'The following are Google-internal bug numbers where explicit permission from\n'
    r'some authors is recorded for use of their work\. \(This is purely for our own\n'
    r'record keeping\.\)\n+'
    r'[0-9+ \n]+\n+'
    r'(' // 1
    r' *OpenSSL License\n'
    r' *---------------\n+)'
    r'(.+?)\n+' // 2
    r'(' // 3
    r' *Original SSLeay License\n'
    r' *-----------------------\n+)'
    r'(.+?)\n+' // 4
    r'( *ISC license used for completely new code in BoringSSL:\n+)' // 5
    r'(.+?)\n+' // 6
    r'( *The code in third_party/fiat carries the MIT license:\n+)' // 7
    r'(.+?)\n+' // 8
    r'(' // 9
    r' *Licenses for support code\n'
    r' *-------------------------\n+)'
    r'(.+?)\n+' // 10
    r'(BoringSSL uses the Chromium test infrastructure to run a continuous build,\n' // 11
    r'trybots etc\. The scripts which manage this, and the script for generating build\n'
    r'metadata, are under the Chromium license\. Distributing code linked against\n'
    r'BoringSSL does not trigger this license\.)\n+'
    r'(.+?)\n+$', // 12
    dotAll: true,
  );

  static License _parseLicense(fs.TextFile io) {
    final Match? match = _pattern.firstMatch(io.readString());
    if (match == null) {
      throw 'Failed to match OpenSSL license pattern.';
    }
    assert(match.groupCount == 12);
    return License.fromMultipleBlocks(
      List<String>.generate(match.groupCount, (int index) => match.group(index + 1)!).toList(),
      LicenseType.openssl,
      origin: io.fullName,
      authors: 'The OpenSSL Project Authors',
      yesWeKnowWhatItLooksLikeButItIsNot: true, // looks like BSD, but...
    );
  }
}

class _RepositoryFuchsiaSdkLinuxLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryFuchsiaSdkLinuxLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static const String _pattern = 'The majority of files in this project use the Apache 2.0 License.\n'
                                 'There are a few exceptions and their license can be found in the source.\n'
                                 'Any license deviations from Apache 2.0 are "more permissive" licenses.\n';

  static License _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    if (!body.startsWith(_pattern)) {
      throw 'unexpected Fuchsia license file contents';
    }
    return License.fromBodyAndType(body.substring(_pattern.length), LicenseType.apache, origin: io.fullName);
  }
}

/// The BoringSSL license file.
///
/// This file contains a bunch of different licenses, but other files
/// refer to it as if it was a monolithic license so we sort of have
/// to treat the whole thing as a MultiLicense.
class _RepositoryVulkanApacheLicenseFile extends _RepositorySingleLicenseFile {
  _RepositoryVulkanApacheLicenseFile(_RepositoryDirectory parent, fs.TextFile io)
    : super(parent, io, _parseLicense(io));

  static const String _prefix =
    'The majority of files in this project use the Apache 2.0 License.\n'
    'There are a few exceptions and their license can be found in the source.\n'
    'Any license deviations from Apache 2.0 are "more permissive" licenses.\n'
    "Any file without a license in it's source defaults to the repository Apache 2.0 License.\n"
    '\n'
    '===========================================================================================\n'
    '\n';

  static License _parseLicense(fs.TextFile io) {
    final String body = io.readString();
    if (!body.startsWith(_prefix)) {
      throw 'Failed to match Vulkan Apache license prefix.';
    }
    return License.fromBody(body.substring(_prefix.length), origin: io.fullName);
  }
}


// DIRECTORIES

typedef _Constructor = _RepositoryFile Function(_RepositoryDirectory parent, fs.TextFile);

class _RepositoryDirectory extends _RepositoryEntry implements LicenseSource {
  _RepositoryDirectory(super.parent, fs.Directory super.io) {
    crawl();
  }

  fs.Directory get ioDirectory => super.io as fs.Directory;
  fs.Directory get rootDirectory => parent != null ? parent!.rootDirectory : ioDirectory;

  final List<_RepositoryDirectory> _subdirectories = <_RepositoryDirectory>[];
  final List<_RepositoryLicensedFile> _files = <_RepositoryLicensedFile>[];
  final List<_RepositoryLicenseFile> _licenses = <_RepositoryLicenseFile>[];
  static final List<fs.IoNode> _excluded = <fs.IoNode>[];

  List<_RepositoryDirectory> get subdirectories => _subdirectories;

  final Map<String,_RepositoryEntry> _childrenByName = <String,_RepositoryEntry>{};

  void crawl() {
    for (final fs.IoNode entry in ioDirectory.walk) {
      if (shouldRecurse(entry)) {
        assert(!_childrenByName.containsKey(entry.name));
        if (entry is fs.Directory) {
          final _RepositoryDirectory child = createSubdirectory(entry);
          _subdirectories.add(child);
          _childrenByName[child.name] = child;
        } else if (entry is fs.File) {
          try {
            final _RepositoryFile child = createFile(entry);
            if (child is _RepositoryLicensedFile) {
              _files.add(child);
            } else {
              assert(child is _RepositoryLicenseFile);
              _licenses.add(child as _RepositoryLicenseFile);
            }
            _childrenByName[child.name] = child;
          } catch (error, stack) {
            throw 'failed to handle $entry\n$error\nOriginal stack:\n$stack';
          }
        } else {
          assert(entry is fs.Link);
        }
      } else {
        _excluded.add(entry);
      }
    }
    for (final _RepositoryDirectory child in virtualSubdirectories) {
      _subdirectories.add(child);
      _childrenByName[child.name] = child;
    }
  }

  // Override this to add additional child directories that do not represent a
  // direct child of this directory's filesystem node.
  List<_RepositoryDirectory> get virtualSubdirectories => <_RepositoryDirectory>[];

  bool shouldRecurse(fs.IoNode entry) {
    if (entry is fs.File) {
      if (skippedCommonFiles.contains(entry.name)) {
        return false;
      }
      if (skippedCommonExtensions.contains(path.extension(entry.name))) {
        return false;
      }
    } else if (entry is fs.Directory) {
      if (skippedCommonDirectories.contains(entry.name)) {
        return false;
      }
    } else {
      throw 'unexpected entry type ${entry.runtimeType}: ${entry.fullName}';
    }
    final String target = path.relative(entry.fullName, from: rootDirectory.fullName);
    if (skippedPaths.contains(target)) {
      return false;
    }
    for (final Pattern pattern in skippedFilePatterns) {
      if (target.contains(pattern)) {
        return false;
      }
    }
    return true;
  }

  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'third_party') {
      return _RepositoryGenericThirdPartyDirectory(this, entry);
    }
    return _RepositoryDirectory(this, entry);
  }

  // the bit at the beginning excludes files like "license.py".
  static final RegExp _licenseNamePattern = RegExp(r'^(?!.*\.py$)(?!.*(?:no|update)-copyright)(?!.*mh-bsd-gcc).*\b_*(?:license(?!\.html)|copying|copyright|notice|l?gpl|GPLv2|bsd|mit|mpl?|ftl|Apache)_*\b', caseSensitive: false);

  static const Map<String, _Constructor> _specialCaseFiles = <String, _Constructor>{
    '/fuchsia/sdk/linux/LICENSE.vulkan': _RepositoryFuchsiaSdkLinuxLicenseFile.new,
    '/fuchsia/sdk/mac/LICENSE.vulkan': _RepositoryFuchsiaSdkLinuxLicenseFile.new,
    '/third_party/boringssl/src/LICENSE': _RepositoryOpenSSLLicenseFile.new,
    '/third_party/dart/LICENSE': _RepositoryDartLicenseFile.new,
    '/third_party/freetype2/LICENSE.TXT': _RepositoryFreetypeLicenseFile.new,
    '/third_party/icu/LICENSE': _RepositoryIcuLicenseFile.new,
    '/third_party/khronos/LICENSE': _RepositoryKhronosLicenseFile.new,
    '/third_party/libcxx/LICENSE.TXT': _RepositoryCxxStlDualLicenseFile.new,
    '/third_party/libcxxabi/LICENSE.TXT': _RepositoryCxxStlDualLicenseFile.new,
    '/third_party/libjpeg-turbo/LICENSE': _RepositoryLibJpegTurboLicenseFile.new,
    '/third_party/libjpeg-turbo/README.ijg': _RepositoryReadmeIjgFile.new,
    '/third_party/libpng/LICENSE': _RepositoryLibPngLicenseFile.new,
    '/third_party/rapidjson/LICENSE': _RepositoryOpaqueLicenseFile.new,
    '/third_party/rapidjson/license.txt': _RepositoryOpaqueLicenseFile.new,
    '/third_party/root_certificates/LICENSE': _RepositoryMpl2File.new,
    '/third_party/vulkan-deps/vulkan-validation-layers/src/LICENSE.txt': _RepositoryVulkanApacheLicenseFile.new,
    '/third_party/inja/third_party/include/nlohmann/json.hpp': _RepositoryInjaJsonFile.new,
  };

  _RepositoryFile createFile(fs.IoNode entry) {
    final String key = '/${path.relative(entry.fullName, from: rootDirectory.fullName)}';
    final _Constructor? constructor = _specialCaseFiles[key];
    if (entry is fs.TextFile) {
      if (constructor != null) {
        return constructor(this, entry);
      }
      if (entry.name.contains(_licenseNamePattern)) {
        return _RepositoryGeneralSingleLicenseFile(this, entry);
      }
      return _RepositorySourceFile(this, entry);
    }
    return _RepositoryBinaryFile(this, entry as fs.File);
  }

  int get count => _files.length + _subdirectories.fold<int>(0, (int count, _RepositoryDirectory child) => count + child.count);

  bool _canGoUp() {
    assert(parent != null || isLicenseRoot);
    return isLicenseRootException || (!isLicenseRoot && !parent!.subdirectoriesAreLicenseRoots);
  }

  @override
  List<License> nearestLicensesFor(String name) {
    if (_licenses.isEmpty) {
      if (_canGoUp()) {
        return parent!.nearestLicensesFor('${io.name}/$name');
      }
      return const <License>[];
    }
    return _licenses.expand((_RepositoryLicenseFile license) {
      return license.licensesFor(name);
    }).toList();
  }

  final Map<LicenseType, License?> _nearestLicenseOfTypeCache = <LicenseType, License?>{};

  /// Searches the current directory, all parent directories up to the license
  /// root, and all their descendants, for a license of the specified type.
  @override
  License? nearestLicenseOfType(LicenseType type) {
    return _nearestLicenseOfTypeCache.putIfAbsent(type, () {
      final License? result = _localLicenseWithType(type);
      if (result != null) {
        return result;
      }
      if (_canGoUp()) {
        return parent!.nearestLicenseOfType(type);
      }
      return _fullWalkDownForLicenseWithType(type);
    });
  }

  /// Searches the current directory for licenses of the specified type.
  License? _localLicenseWithType(LicenseType type) {
    final List<License> licenses = _licenses.expand((_RepositoryLicenseFile license) {
      final License? result = license.licenseOfType(type);
      if (result != null) {
        return <License>[result];
      }
      return const <License>[];
    }).toList();
    if (licenses.length > 1) {
      print('unexpectedly found multiple matching licenses in $name of type $type');
      return null;
    }
    if (licenses.isNotEmpty) {
      return licenses.single;
    }
    return null;
  }

  /// Searches all subdirectories (depth-first) for a license of the specified type.
  License? _fullWalkDownForLicenseWithType(LicenseType type) {
    for (final _RepositoryDirectory directory in _subdirectories) {
      if (directory._canGoUp()) { // avoid crawling into other license scopes
        final License? result = directory._localLicenseWithType(type) ?? directory._fullWalkDownForLicenseWithType(type);
        if (result != null) {
          return result;
        }
      }
    }
    return null;
  }

  final Map<String, License?> _nearestLicenseWithNameCache = <String, License?>{};

  @override
  License? nearestLicenseWithName(String name, {String? authors}) {
    assert(!name.contains('\x00'));
    assert(authors == null || !authors.contains('\x00'));
    assert(authors == null || authors != '${null}');
    final License? result = _nearestLicenseWithNameCache.putIfAbsent('$name\x00$authors', () {
      final License? result = _localLicenseWithName(name, authors: authors);
      if (result != null) {
        return result;
      }
      if (_canGoUp()) {
        return parent!.nearestLicenseWithName(name, authors: authors);
      }
      return _fullWalkDownForLicenseWithName(name, authors: authors)
          ?? (authors != null ? parent?._fullWalkUpForLicenseWithName(name, authors: authors) : null);
    });
    return result;
  }

  License? _localLicenseWithName(String name, { String? authors }) {
    final _RepositoryEntry? entry = _childrenByName[name];
    License? license;
    if (entry is _RepositoryLicensedFile) {
      license = entry.extractInternalLicense();
    } else if (entry is _RepositoryLicenseFile) {
      license = entry.defaultLicense;
    } else if (entry != null) {
      if (authors == null) {
        throw 'found "$name" in $this but it was a ${entry.runtimeType}';
      }
    }
    if (license != null && authors != null && authors != license.authors) {
      license = null;
    }
    return license;
  }

  License? _fullWalkUpForLicenseWithName(String name, { required String authors }) {
    // When looking for a license specific to certain authors, we want to walk
    // to the top of the local license root, then from there check all the
    // ancestors and all the descendants.
    //
    // We check even the ancestors (on the other side of license root
    // boundaries) for this because when we know which authors we're looking
    // for, it's reasonable to look all the way up the tree (e.g. the Flutter
    // Authors license is at the root, and is sometimes mentioned in various
    // files deep inside third party directories).
    return _localLicenseWithName(name, authors: authors) ??
           parent?._fullWalkUpForLicenseWithName(name, authors: authors);
  }

  License? _fullWalkDownForLicenseWithName(String name, { String? authors }) {
    for (final _RepositoryDirectory directory in _subdirectories) {
      if (directory._canGoUp()) { // avoid crawling into other license scopes
        final License? result = directory._localLicenseWithName(name, authors: authors)
                             ?? directory._fullWalkDownForLicenseWithName(name, authors: authors);
        if (result != null) {
          return result;
        }
      }
    }
    return null;
  }

  /// Unless isLicenseRootException is true, we should not walk up the tree from
  /// here looking for licenses.
  bool get isLicenseRoot => parent == null;

  /// Unless isLicenseRootException is true on a child, the child should not
  /// walk up the tree to here looking for licenses.
  bool get subdirectoriesAreLicenseRoots => false;

  @override
  String get libraryName {
    if (isLicenseRoot || parent!.subdirectoriesAreLicenseRoots) {
      return name;
    }
    if (parent!.parent == null) {
      throw '$this is not a license root';
    }
    return parent!.libraryName;
  }

  /// Overrides isLicenseRoot and parent.subdirectoriesAreLicenseRoots for cases
  /// where a directory contains license roots instead of being one. This
  /// allows, for example, the expat third_party directory to contain a
  /// subdirectory with expat while itself containing a BUILD file that points
  /// to the LICENSE in the root of the repo.
  bool get isLicenseRootException => false;

  _RepositoryEntry getChildByName(String name) {
    assert(_childrenByName.containsKey(name), 'missing $name in ${io.fullName}');
    return _childrenByName[name]!;
  }

  Iterable<Assignment> assignLicenses(_Progress progress) {
    final List<Assignment> result = <Assignment>[];
    // Report licenses for files in this directory
    for (final _RepositoryLicensedFile file in _files) {
      try {
        progress.label = '$file';
        final Iterable<Assignment> licenses = file.assignLicenses();
        assert(licenses.isNotEmpty);
        result.addAll(licenses);
        progress.advance(success: true);
      } catch (e, stack) {
        system.stderr.writeln('\nerror searching for copyright in: ${file.io}\n$e');
        if (e is! String) {
          system.stderr.writeln(stack);
        }
        system.stderr.writeln('\n');
        progress.advance(success: false);
      }
    }
    // Recurse to subdirectories
    for (final _RepositoryDirectory directory in _subdirectories) {
      result.addAll(directory.assignLicenses(progress));
    }
    return result;
  }

  int get fileCount {
    int result = _files.length;
    for (final _RepositoryDirectory directory in _subdirectories) {
      result += directory.fileCount;
    }
    return result;
  }

  Iterable<_RepositoryLicensedFile> get _signatureFiles sync* {
    for (final _RepositoryLicensedFile file in _files) {
      yield file;
    }
    for (final _RepositoryDirectory directory in _subdirectories) {
      if (directory.includeInSignature) {
        yield* directory._signatureFiles;
      }
    }
  }

  Stream<List<int>> _signatureStream(List<_RepositoryLicensedFile> files) async* {
    for (final _RepositoryLicensedFile file in files) {
      yield file.io.fullName.codeUnits;
      yield file.ioFile.readBytes()!;
    }
  }

  /// Compute a signature representing a hash of all the licensed files within
  /// this directory tree.
  Future<String> get signature async {
    final List<_RepositoryLicensedFile> allFiles = _signatureFiles.toList();
    allFiles.sort((_RepositoryLicensedFile a, _RepositoryLicensedFile b) =>
        a.io.fullName.compareTo(b.io.fullName));
    final crypto.Digest digest = await crypto.md5.bind(_signatureStream(allFiles)).single;
    return digest.bytes.map((int e) => e.toRadixString(16).padLeft(2, '0')).join();
  }

  /// True if this directory's contents should be included when computing the signature.
  bool get includeInSignature => true;

  @override
  String get officialSourceLocation {
    throw 'license requested source location for directory that should not need it';
  }
}

class _RepositoryReachOutFile extends _RepositoryLicensedFile {
  _RepositoryReachOutFile(super.parent, super.io, this.offset);

  final int offset;

  @override
  Iterable<Assignment> assignLicenses() {
    _RepositoryDirectory? directory = parent;
    int index = offset;
    while (index > 1) {
      if (directory == null) {
        break;
      }
      directory = directory.parent;
      index -= 1;
    }
    return directory!.nearestLicensesFor(name).map((License license) => license.assignLicenses(io.fullName, parent!));
  }
}

class _RepositoryReachOutDirectory extends _RepositoryDirectory {
  _RepositoryReachOutDirectory(_RepositoryDirectory super.parent, super.io, this.reachOutFilenames, this.offset);

  final Set<String> reachOutFilenames;
  final int offset;

  @override
  _RepositoryFile createFile(fs.IoNode entry) {
    if (reachOutFilenames.contains(entry.name)) {
      return _RepositoryReachOutFile(this, entry as fs.File, offset);
    }
    return super.createFile(entry);
  }
}

class _RepositoryInjaJsonFile extends _RepositorySourceFile {
  _RepositoryInjaJsonFile(super.parent, super.io);
  @override
  License extractInternalLicense() {
    throw '$this does not have a clearly extractable license';
  }

  static final RegExp _pattern = RegExp(
    r'^(.*?)' // 1
    r'Licensed under the MIT License <http://opensource\.org/licenses/MIT>\.\n'
    r'SPDX-License-Identifier: MIT\n'
    r'(Copyright \(c\) 2013-2019 Niels Lohmann <http://nlohmann\.me>\.)\n' // 2
    r'\n'
    r'(Permission is hereby  granted, free of charge, to any  person obtaining a copy\n' // 3
    r'of this software and associated  documentation files \(the "Software"\), to deal\n'
    r'in the Software  without restriction, including without  limitation the rights\n'
    r'to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell\n'
    r'copies  of  the Software,  and  to  permit persons  to  whom  the Software  is\n'
    r'furnished to do so, subject to the following conditions:\n'
    r'\n'
    r'The above copyright notice and this permission notice shall be included in all\n'
    r'copies or substantial portions of the Software\.\n'
    r'\n'
    r'THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR\n'
    r'IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,\n'
    r'FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT\. IN NO EVENT  SHALL THE\n'
    r'AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER\n'
    r'LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n'
    r'OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE\n'
    r'SOFTWARE\.)\n'
    r'(.*?)' // 4
    r' \* Created by Evan Nemerson <evan@nemerson\.com>\n'
    r' \*\n'
    r' \* To the extent possible under law, the author\(s\) have dedicated all\n'
    r' \* copyright and related and neighboring rights to this software to\n'
    r' \* the public domain worldwide\. This software is distributed without\n'
    r' \* any warranty\.\n'
    r' \*\n'
    r' \* For details, see <http://creativecommons\.org/publicdomain/zero/1\.0/>\.\n'
    r' \* SPDX-License-Identifier: CC0-1\.0\n'
    r'(.*?)' // 5
    r'The code is distributed under the MIT license, (Copyright \(c\) 2009 Florian Loitsch\.)\n' // 6
    r'(.*?)' // 7
    r'    @copyright (Copyright \(c\) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann\.de>)\n' // 8
    r'(.*?)' // 9
    r'    `copyright` \| The copyright line for the library as string\.\n'
    r'(.*?)' // 10
    r'        result\["copyright"\] = "\(C\) 2013-2020 Niels Lohmann";\n'
    r'(.*)$', // 11
    dotAll: true, // isMultiLine is false, so ^ and $ only match start and end.
  );

  @override
  Iterable<Assignment> assignLicenses() {
    if (_internalLicenses == null) {
      final Match? match = _pattern.matchAsPrefix(_contents);
      if (match == null) {
        throw '${io.fullName} has changed contents.';
      }
      final String license = match.group(3)!;
      _internalLicenses = match.groups(const <int>[ 2, 6, 8 ]).map<License>((String? copyright) {
        assert(copyright!.contains('Copyright'));
        return License.fromCopyrightAndLicense(copyright!, license, LicenseType.mit, origin: io.fullName);
      }).toList();
      assert(!match.groups(const <int>[ 1, 4, 5, 7, 9, 10, 11]).any((String? text) => text!.contains(copyrightMentionPattern)));
    }
    return _internalLicenses!.map((License license) => license.assignLicenses(io.fullName, parent!));
  }
}

/// The `src/` directory created by gclient sync (a.k.a. buildroot).
///
/// This directory is the parent of the flutter/engine repository. The license
/// crawler begins its search starting from this directory and recurses down
/// from it.
///
/// This is not the root of the flutter/engine repository.
/// [_RepositoryFlutterDirectory] represents that.
class _EngineSrcDirectory extends _RepositoryDirectory {
  _EngineSrcDirectory(fs.Directory io) : super(null, io);

  @override
  String get libraryName {
    throw 'Package failed to determine library name.';
  }

  @override
  bool get isLicenseRoot => true;

  @override
  bool get subdirectoriesAreLicenseRoots => false;

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'third_party') {
      return _RepositoryRootThirdPartyDirectory(this, entry);
    }
    if (entry.name == 'flutter') {
      return _RepositoryFlutterDirectory(this, entry);
    }
    if (entry.name == 'gpu') {
      return _RepositoryGpuShimDirectory(this, entry);
    }
    if (entry.name == 'fuchsia') {
      return _RepositoryFuchsiaDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }

  @override
  List<_RepositoryDirectory> get virtualSubdirectories {
    // Skia is updated more frequently than other third party libraries and
    // is therefore represented as a separate top-level component.
    final fs.Directory thirdPartyNode = findChildDirectory(ioDirectory, 'third_party')!;
    final fs.Directory skiaNode = findChildDirectory(thirdPartyNode, 'skia')!;
    final fs.Directory dartNode = findChildDirectory(thirdPartyNode, 'dart')!;
    return <_RepositoryDirectory>[
      _RepositorySkiaDirectory(this, skiaNode),
      _RepositorySkiaDirectory(this, dartNode),
    ];
  }
}

class _RepositoryGenericThirdPartyDirectory extends _RepositoryDirectory {
  _RepositoryGenericThirdPartyDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  bool get subdirectoriesAreLicenseRoots => true;
}

class _RepositoryRootThirdPartyDirectory extends _RepositoryGenericThirdPartyDirectory {
  _RepositoryRootThirdPartyDirectory(super.parent, super.io);

  @override
  bool shouldRecurse(fs.IoNode entry) {
    return entry.name != 'skia' // handled as a virtual directory of the root
        && entry.name != 'dart' // handled as a virtual directory of the root
        && super.shouldRecurse(entry);
  }

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'boringssl') {
      return _RepositoryBoringSSLDirectory(this, entry);
    }
    if (entry.name == 'expat') {
      return _RepositoryExpatDirectory(this, entry);
    }
    if (entry.name == 'freetype2') {
      return _RepositoryFreetypeDirectory(this, entry);
    }
    if (entry.name == 'icu') {
      return _RepositoryIcuDirectory(this, entry);
    }
    if (entry.name == 'root_certificates') {
      return _RepositoryRootCertificatesDirectory(this, entry);
    }
    if (entry.name == 'vulkan-deps') {
      return _RepositoryGenericThirdPartyDirectory(this, entry);
    }
    if (entry.name == 'zlib') {
      return _RepositoryZLibDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositoryExpatDirectory extends _RepositoryDirectory {
  _RepositoryExpatDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  bool get isLicenseRootException => true;

  @override
  bool get subdirectoriesAreLicenseRoots => true;
}

class _RepositoryFreetypeDirectory extends _RepositoryDirectory {
  _RepositoryFreetypeDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  List<License> nearestLicensesFor(String name) {
    final List<License> result = super.nearestLicensesFor(name);
    if (result.isEmpty) {
      final License? license = nearestLicenseWithName('LICENSE.TXT');
      assert(license != null);
      if (license != null) {
        return <License>[license];
      }
    }
    return result;
  }

  @override
  License? nearestLicenseOfType(LicenseType type) {
    if (type == LicenseType.freetype) {
      final License? result = nearestLicenseWithName('FTL.TXT');
      assert(result != null);
      return result;
    }
    return super.nearestLicenseOfType(type);
  }

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'src') {
      return _RepositoryFreetypeSrcDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositoryFreetypeSrcDirectory extends _RepositoryDirectory {
  _RepositoryFreetypeSrcDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'gzip') {
      return _RepositoryFreetypeSrcGZipDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositoryFreetypeSrcGZipDirectory extends _RepositoryDirectory {
  _RepositoryFreetypeSrcGZipDirectory(_RepositoryDirectory super.parent, super.io);

  // advice was to make this directory's inffixed.h file (which has no license)
  // use the license in zlib.h.

  @override
  List<License> nearestLicensesFor(String name) {
    final License? zlib = nearestLicenseWithName('zlib.h');
    assert(zlib != null);
    if (zlib != null) {
      return <License>[zlib];
    }
    return super.nearestLicensesFor(name);
  }

  @override
  License? nearestLicenseOfType(LicenseType type) {
    if (type == LicenseType.zlib) {
      final License? result = nearestLicenseWithName('zlib.h');
      assert(result != null);
      return result;
    }
    return super.nearestLicenseOfType(type);
  }
}

class _RepositoryIcuDirectory extends _RepositoryDirectory {
  _RepositoryIcuDirectory(super.parent, super.io);

  @override
  _RepositoryFile createFile(fs.IoNode entry) {
    if (entry.name == 'LICENSE') {
      return _RepositoryIcuLicenseFile(this, entry as fs.TextFile);
    }
    return super.createFile(entry);
  }
}

class _RepositoryRootCertificatesDirectory extends _RepositoryDirectory {
  _RepositoryRootCertificatesDirectory(_RepositoryDirectory super.parent, super.io);

  static final RegExp _revinfoPattern = RegExp(r'^([^:]+): ([^@]+)@(.+)$');

  @override
  String get officialSourceLocation {
    final system.ProcessResult result = system.Process.runSync('gclient', <String>['revinfo'], workingDirectory: '$this');
    if (result.exitCode != 0) {
      throw 'Failed to run "gclient revinfo"; got non-zero exit code ${result.exitCode}\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}';
    }
    final List<String> matchingLines = (result.stdout as String).split('\n').where((String line) => line.startsWith('src/third_party/root_certificates:')).toList();
    if (matchingLines.length != 1) {
      throw 'Failed to find root_certificates in "gclient revinfo" output:\n${result.stdout}';
    }
    final Match? match = _revinfoPattern.matchAsPrefix(matchingLines.single);
    if (match == null) {
      throw 'Failed to find root_certificates in "gclient revinfo" output:\n${result.stdout}';
    }
    if ((match.group(1) != 'src/third_party/root_certificates') ||
        (match.group(2) != 'https://dart.googlesource.com/root_certificates.git')) {
      throw 'Failed to verify root_certificates entry in "gclient revinfo" output:\n${result.stdout}';
    }
    return 'https://dart.googlesource.com/root_certificates/+/${match.group(3)}';
  }
}

class _RepositoryZLibDirectory extends _RepositoryDirectory {
  _RepositoryZLibDirectory(_RepositoryDirectory super.parent, super.io);

  // Some files in this directory refer to "MiniZip_info.txt".
  // As best we can tell, that refers to a file that itself includes the
  // exact same license text as in LICENSE.

  @override
  License? nearestLicenseWithName(String name, { String? authors }) {
    if (name == 'MiniZip_info.txt') {
      return super.nearestLicenseWithName('LICENSE', authors: authors)!;
    }
    return super.nearestLicenseWithName(name, authors: authors);
  }

  @override
  License? nearestLicenseOfType(LicenseType type) {
    if (type == LicenseType.zlib) {
      return nearestLicenseWithName('LICENSE')!;
    }
    return super.nearestLicenseOfType(type);
  }
}

class _RepositorySkiaDirectory extends _RepositoryDirectory {
  _RepositorySkiaDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  bool get isLicenseRoot => true;

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'third_party') {
      return _RepositorySkiaThirdPartyDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositorySkiaThirdPartyDirectory extends _RepositoryGenericThirdPartyDirectory {
  _RepositorySkiaThirdPartyDirectory(super.parent, super.io);

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'ktx') {
      return _RepositoryReachOutDirectory(this, entry, const <String>{'ktx.h', 'ktx.cpp'}, 2);
    }
    if (entry.name == 'libmicrohttpd') {
      return _RepositoryReachOutDirectory(this, entry, const <String>{'MHD_config.h'}, 2);
    }
    if (entry.name == 'libwebp') {
      return _RepositorySkiaLibWebPDirectory(this, entry);
    }
    if (entry.name == 'libsdl') {
      return _RepositorySkiaLibSdlDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositorySkiaLibWebPDirectory extends _RepositoryDirectory {
  _RepositorySkiaLibWebPDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'webp') {
      return _RepositoryReachOutDirectory(this, entry, const <String>{'config.h'}, 3);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositorySkiaLibSdlDirectory extends _RepositoryDirectory {
  _RepositorySkiaLibSdlDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  bool get isLicenseRootException => true;
}

class _RepositoryBoringSSLDirectory extends _RepositoryDirectory {
  _RepositoryBoringSSLDirectory(_RepositoryDirectory super.parent, super.io);

  // This directory contains boringssl itself in the 'src' subdirectory,
  // and the rest of files are code generated from tools in that directory.
  // We redirect any license queries to the src/LICENSE file.

  _RepositoryDirectory get src => getChildByName('src') as _RepositoryDirectory;

  @override
  List<License> nearestLicensesFor(String name) {
    final List<License> result = super.nearestLicensesFor(name);
    if (result.isEmpty) {
      return (src.getChildByName('LICENSE') as _RepositoryLicenseFile).licenses;
    }
    return result;
  }

  @override
  License? nearestLicenseOfType(LicenseType type) {
    assert(!src._canGoUp());
    return super.nearestLicenseOfType(type) ?? src.nearestLicenseOfType(type);
  }

  @override
  License? nearestLicenseWithName(String name, {String? authors}) {
    assert(!src._canGoUp());
    final License? result = super.nearestLicenseWithName(name, authors: authors) ?? src.nearestLicenseWithName(name, authors: authors);
    return result;
  }

  @override
  _RepositoryDirectory createSubdirectory(fs.Directory entry) {
    if (entry.name == 'src') {
      // This is the actual BoringSSL library.
      return _RepositoryBoringSSLSourceDirectory(this, entry);
    }
    return super.createSubdirectory(entry);
  }
}

class _RepositoryBoringSSLSourceDirectory extends _RepositoryDirectory {
  _RepositoryBoringSSLSourceDirectory(_RepositoryDirectory super.parent, super.io);

  // This directory is called "src" because of the way we import boringssl. The
  // parent is called "boringssl". Since we are a licenseRoot, the default
  // "libraryName" implementation would use "src", so we force it to go up here.
  @override
  String get libraryName => parent!.libraryName;

  @override
  bool get isLicenseRoot => true;
}

class _RepositoryFlutterDirectory extends _RepositoryDirectory {
  _RepositoryFlutterDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  String get libraryName => 'engine';

  @override
  bool get isLicenseRoot => true;
}

class _RepositoryFuchsiaDirectory extends _RepositoryDirectory {
  _RepositoryFuchsiaDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  String get libraryName => 'fuchsia_sdk';

  @override
  bool get isLicenseRoot => true;
}

class _RepositoryGpuShimDirectory extends _RepositoryDirectory {
  _RepositoryGpuShimDirectory(_RepositoryDirectory super.parent, super.io);

  @override
  String get libraryName => 'engine';
}


/// The license tool directory.
///
/// This is a special-case root node that is not used for license aggregation,
/// but simply to compute a signature for the license tool itself. When this
/// signature changes, we force re-run license collection for all components in
/// order to verify the tool itself still produces the same output.
class _RepositoryFlutterLicenseToolDirectory extends _RepositoryDirectory {
  _RepositoryFlutterLicenseToolDirectory(fs.Directory io) : super(null, io);

  @override
  bool shouldRecurse(fs.IoNode entry) {
    return entry.name != 'data' && super.shouldRecurse(entry);
  }
}


// BOOTSTRAPPING LOGIC

fs.Directory? findChildDirectory(fs.Directory parent, String name) {
  return parent.walk.firstWhereOrNull( // from IterableExtension in package:collection
    (fs.IoNode child) => child.name == name,
  ) as fs.Directory?;
}

class _Progress {
  _Progress(this.max, {this.quiet = false}) : millisecondsBetweenUpdates = quiet ? 10000 : 0 {
    // This may happen when a git client contains left-over empty component
    // directories after DEPS file changes.
    if (max <= 0) {
      throw ArgumentError('Progress.max must be > 0 but was: $max');
    }
  }

  final int max;
  final bool quiet;
  final int millisecondsBetweenUpdates;
  int get withLicense => _withLicense;
  int _withLicense = 0;
  int get withoutLicense => _withoutLicense;
  int _withoutLicense = 0;
  String get label => _label;
  String _label = '';
  int _lastLength = 0;
  set label(String value) {
    if (value.length > 60) {
      value = '.../${value.substring(math.max(0, value.lastIndexOf('/', value.length - 45) + 1))}';
    }
    if (_label != value) {
      _label = value;
      update();
    }
  }

  void advance({required bool success}) {
    if (success) {
      _withLicense += 1;
    } else {
      _withoutLicense += 1;
    }
    update();
  }

  Stopwatch? _lastUpdate;
  void update({bool flush = false}) {
    if (_lastUpdate == null || _lastUpdate!.elapsedMilliseconds >= millisecondsBetweenUpdates || flush) {
      _lastUpdate ??= Stopwatch();
      if (!quiet) {
        final String line = toString();
        system.stderr.write('\r$line');
        if (_lastLength > line.length) {
          system.stderr.write(' ' * (_lastLength - line.length));
        }
        _lastLength = line.length;
      }
      _lastUpdate!.reset();
      _lastUpdate!.start();
    }
  }

  void flush() => update(flush: true);
  bool get hadErrors => _withoutLicense > 0;
  @override
  String toString() {
    final int percent = (100.0 * (_withLicense + _withoutLicense) / max).round();
    return '${(_withLicense + _withoutLicense).toString().padLeft(10)} of ${max.toString().padRight(6)} '
           '${'█' * (percent ~/ 10)}${'░' * (10 - (percent ~/ 10))} $percent% '
           '${ _withoutLicense > 0 ? "($_withoutLicense missing licenses) " : ""}'
           '$label';
  }
}

final RegExp _signaturePattern = RegExp(r'^Signature: (\w+)$', multiLine: true, expectNoMatch: true);

/// Reads the signature from a golden file.
String? _readSignature(String goldenPath) {
  try {
    final system.File goldenFile = system.File(goldenPath);
    if (!goldenFile.existsSync()) {
      system.stderr.writeln('    Could not find signature file ($goldenPath).');
      return null;
    }
    final String goldenSignature = goldenFile.readAsStringSync();
    final Match? goldenMatch = _signaturePattern.matchAsPrefix(goldenSignature);
    if (goldenMatch != null) {
      return goldenMatch.group(1);
    }
    system.stderr.writeln('    Signature file ($goldenPath) did not match expected pattern.');
  } on system.FileSystemException {
    system.stderr.writeln('    Failed to read signature file ($goldenPath).');
    return null;
  }
  return null;
}

/// Writes a signature to an [system.IOSink] in the expected format.
void _writeSignature(String signature, system.IOSink sink) {
  sink.writeln('Signature: $signature\n');
}

// Checks for changes to the license tool itself.
//
// Returns true if changes are detected.
Future<bool> _computeLicenseToolChanges(_RepositoryDirectory root, { required String goldenSignaturePath, required String outputSignaturePath }) async {
  final fs.Directory flutterNode = findChildDirectory(root.ioDirectory, 'flutter')!;
  final fs.Directory toolsNode = findChildDirectory(flutterNode, 'tools')!;
  final fs.Directory licenseNode = findChildDirectory(toolsNode, 'licenses')!;
  final _RepositoryDirectory licenseToolDirectory = _RepositoryFlutterLicenseToolDirectory(licenseNode);
  final String toolSignature = await licenseToolDirectory.signature;
  final system.IOSink sink = system.File(outputSignaturePath).openWrite();
  _writeSignature(toolSignature, sink);
  await sink.close();
  final String? goldenSignature = _readSignature(goldenSignaturePath);
  return toolSignature != goldenSignature;
}

/// Collects licenses for the specified component.
///
/// If [writeSignature] is set, the signature is written to the output file.
/// If [force] is set, collection is run regardless of whether or not the signature matches.
Future<void> _collectLicensesForComponent(_RepositoryDirectory componentRoot, {
  required String inputGoldenPath,
  String? outputGoldenPath,
  required bool writeSignature,
  required bool force,
  required bool quiet,
}) async {
  final String signature = await componentRoot.signature;
  if (writeSignature) {
    // Check whether the golden file matches the signature of the current contents of this directory.
    // (We only do this for components where we write the signature, since if there's no signature,
    // there's no point trying to read it...)
    final String? goldenSignature = _readSignature(inputGoldenPath);
    if (!force && goldenSignature == signature) {
      system.stderr.writeln('    Skipping this component - no change in signature');
      return;
    }
  }

  final _Progress progress = _Progress(componentRoot.fileCount, quiet: quiet);

  final system.File outFile = system.File(outputGoldenPath!);
  final system.IOSink sink = outFile.openWrite();
  if (writeSignature) {
    _writeSignature(signature, sink);
  }

  final List<GroupedLicense> licenses = groupLicenses(componentRoot.assignLicenses(progress));
  if (progress.hadErrors) {
    throw 'Had failures while collecting licenses.';
  }
  progress.label = 'Dumping results...';
  progress.flush();
  final List<String> output = licenses.map((GroupedLicense license) => license.toStringDebug()).toList();
  for (int index = 0; index < output.length; index += 1) {
    // The strings we look for here are strings which we do not expect to see in
    // any of the licenses we use. They either represent examples of misparsing
    // licenses (issues we've previously run into and fixed), or licenses we
    // know we are trying to avoid (e.g. the GPL, or licenses that only apply to
    // test content which shouldn't get built at all).
    // If you find that one of these tests is getting hit, and it's not obvious
    // to you why the relevant license is a problem, please ask around (e.g. try
    // asking Hixie). Do not merely remove one of these checks, sometimes the
    // issues involved are relatively subtle.
    if (output[index].contains('Version: MPL 1.1/GPL 2.0/LGPL 2.1')) {
      throw 'Unexpected trilicense block found in:\n${output[index]}';
    }
    if (output[index].contains('The contents of this file are subject to the Mozilla Public License Version')) {
      throw 'Unexpected MPL block found in:\n${output[index]}';
    }
    if (output[index].contains('You should have received a copy of the GNU')) {
      throw 'Unexpected GPL block found in:\n${output[index]}';
    }
    if (output[index].contains('Contents of this folder are ported from')) {
      throw 'Unexpected block found in:\n${output[index]}';
    }
    if (output[index].contains('https://github.com/w3c/web-platform-tests/tree/master/selectors-api')) {
      throw 'Unexpected W3C content found in:\n${output[index]}';
    }
    if (output[index].contains('http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html')) {
      throw 'Unexpected W3C copyright found in:\n${output[index]}';
    }
    if (output[index].contains('It is based on commit')) {
      throw 'Unexpected content found in:\n${output[index]}';
    }
    if (output[index].contains('The original code is covered by the dual-licensing approach described in:')) {
      throw 'Unexpected old license reference found in:\n${output[index]}';
    }
    if (output[index].contains('must choose')) {
      throw 'Unexpected indecisiveness found in:\n${output[index]}';
    }
  }
  sink.writeln(output.join('\n'));
  sink.writeln('Total license count: ${licenses.length}');

  await sink.close();
  progress.label = 'Done.';
  progress.flush();
  system.stderr.writeln();
}

// MAIN

Future<void> main(List<String> arguments) async {
  final ArgParser parser = ArgParser()
    ..addOption('src', help: 'The root of the engine source.')
    ..addOption('out', help: 'The directory where output is written. (Ignored if used with --release.)')
    ..addOption('golden', help: 'The directory containing golden results.')
    ..addFlag('quiet', help: 'If set, the diagnostic output is much less verbose.')
    ..addFlag('verbose', help: 'If set, print additional information to help with development.')
    ..addFlag('release', help: 'Print output in the format used for product releases.');

  final ArgResults argResults = parser.parse(arguments);
  final bool quiet = argResults['quiet'] as bool;
  final bool verbose = argResults['verbose'] as bool;
  final bool releaseMode = argResults['release'] as bool;
  if (argResults['src'] == null) {
    print('Flutter license script: Must provide --src directory');
    print(parser.usage);
    system.exit(1);
  }
  if (!releaseMode) {
    if (argResults['out'] == null || argResults['golden'] == null) {
      print('Flutter license script: Must provide --out and --golden directories in non-release mode');
      print(parser.usage);
      system.exit(1);
    }
    if (!system.FileSystemEntity.isDirectorySync(argResults['golden'] as String)) {
      print('Flutter license script: Golden directory does not exist');
      print(parser.usage);
      system.exit(1);
    }
    final system.Directory out = system.Directory(argResults['out'] as String);
    if (!out.existsSync()) {
      out.createSync(recursive: true);
    }
  }

  try {
    system.stderr.writeln('Finding files...');
    final fs.FileSystemDirectory rootDirectory = fs.FileSystemDirectory.fromPath(argResults['src'] as String);
    final _RepositoryDirectory root = _EngineSrcDirectory(rootDirectory);

    if (releaseMode) {
      system.stderr.writeln('Collecting licenses...');
      final _Progress progress = _Progress(root.fileCount, quiet: quiet);
      final List<GroupedLicense> licenses = groupLicenses(root.assignLicenses(progress));
      if (progress.hadErrors) {
        throw 'Had failures while collecting licenses.';
      }
      progress.label = 'Dumping results...';
      progress.flush();
      final String output = licenses
        .where((GroupedLicense license) => license.body.isNotEmpty)
        .map((GroupedLicense license) => license.toStringFormal())
        .join('\n${"-" * 80}\n');
      print(output);
      progress.label = 'Done.';
      progress.flush();
      system.stderr.writeln();
    } else {
      // If changes are detected to the license tool itself, force collection
      // for all components in order to check we're still generating correct
      // output.
      const String toolSignatureFilename = 'tool_signature';
      final bool forceRunAll = await _computeLicenseToolChanges(
        root,
        goldenSignaturePath: path.join(argResults['golden'] as String, toolSignatureFilename),
        outputSignaturePath: path.join(argResults['out'] as String, toolSignatureFilename),
      );
      if (forceRunAll) {
        system.stderr.writeln('Detected changes to license tool. Forcing license collection for all components.');
      }
      final List<String> usedGoldens = <String>[];
      bool isFirstComponent = true;
      for (final _RepositoryDirectory component in root.subdirectories) {
        system.stderr.writeln('Collecting licenses for ${component.io.name}');
        _RepositoryDirectory componentRoot;
        if (isFirstComponent) {
          // For the first component, we can use the results of the initial repository crawl.
          isFirstComponent = false;
          componentRoot = component;
        } else {
          // For other components, we need a clean repository that does not
          // contain any state left over from previous components.
          componentRoot = _EngineSrcDirectory(rootDirectory)
              .subdirectories
              .firstWhere((_RepositoryDirectory dir) => dir.name == component.name);
        }
        final String goldenFileName = 'licenses_${component.io.name}';
        await _collectLicensesForComponent(
          componentRoot,
          inputGoldenPath: path.join(argResults['golden'] as String, goldenFileName),
          outputGoldenPath: path.join(argResults['out'] as String, goldenFileName),
          writeSignature: component.io.name != 'flutter',
          // Always run the full license check on the flutter tree. The flutter
          // tree is relatively small and changes frequently in ways that do not
          // affect the license output, and we don't want to require updates to
          // the golden signature for those changes.
          force: forceRunAll || component.io.name == 'flutter',
          quiet: quiet,
        );
        usedGoldens.add(goldenFileName);
      }
      final Set<String> unusedGoldens = system.Directory(argResults['golden'] as String).listSync()
        .map<String>((system.FileSystemEntity file) => path.basename(file.path))
        .where((String name) => name.startsWith('licenses_'))
        .toSet()
        ..removeAll(usedGoldens);
      if (unusedGoldens.isNotEmpty) {
        system.stderr.writeln('The following golden files in ${argResults['golden']} are unused and need to be deleted:');
        unusedGoldens.map((String s) => ' * $s').forEach(system.stderr.writeln);
        system.exit(1);
      }
      // write to disk the list of files we did _not_ cover, so it's easier to catch in diffs
      final String excluded = (_RepositoryDirectory._excluded.map(
        (fs.IoNode node) => node.fullName,
      ).toSet().toList()..sort()).join('\n');
      system.File(path.join(argResults['out'] as String, 'excluded_files')).writeAsStringSync(
        '$excluded\n',
      );
    }
  } catch (e, stack) {
    system.stderr.writeln();
    system.stderr.writeln('failure: $e\n$stack');
    system.stderr.writeln('aborted.');
    system.exit(1);
  } finally {
    if (verbose) {
      RegExp.printDiagnostics();
    }
  }
}
