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

import 'dart:convert' show ByteConversionSink, jsonDecode, utf8;
import 'dart:io' as io;
import 'dart:typed_data';

import 'package:args/command_runner.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart' as crypto;
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;

// ignore: avoid_relative_lib_imports
import '../lib/src/engine/noto_font_encoding.dart';

import 'cipd.dart';
import 'environment.dart';
import 'exceptions.dart';
import 'utils.dart';

const String expectedUrlPrefix = 'https://fonts.gstatic.com/s/';

class RollFallbackFontsCommand extends Command<bool>
    with ArgUtils<bool> {
  RollFallbackFontsCommand() {
    argParser.addOption(
      'key',
      defaultsTo: '',
      help: 'The Google Fonts API key. Used to get data about fonts hosted on '
          'Google Fonts.',
    );
    argParser.addFlag(
      'dry-run',
      help: 'Whether or not to push changes to CIPD. When --dry-run is set, the '
            'script will download everything and attempt to prepare the bundle '
            'but will stop before publishing. When not set, the bundle will be '
            'published.',
      negatable: false,
    );
  }

  @override
  final String name = 'roll-fallback-fonts';

  @override
  final String description = 'Generate fallback font data from GoogleFonts and '
                             'upload fonts to cipd.';

  String get apiKey => stringArg('key');
  bool get isDryRun => boolArg('dry-run');

  @override
  Future<bool> run() async {
    await _generateFallbackFontData();
    return true;
  }

  Future<void> _generateFallbackFontData() async {
    if (apiKey.isEmpty) {
      throw UsageException('No Google Fonts API key provided', argParser.usage);
    }
    final http.Client client = http.Client();
    final http.Response response = await client.get(Uri.parse(
        'https://www.googleapis.com/webfonts/v1/webfonts?key=$apiKey'));
    if (response.statusCode != 200) {
      throw ToolExit('Failed to download Google Fonts list.');
    }
    final Map<String, dynamic> googleFontsResult =
        jsonDecode(response.body) as Map<String, dynamic>;
    final List<Map<String, dynamic>> fontDatas =
        (googleFontsResult['items'] as List<dynamic>)
            .cast<Map<String, dynamic>>();
    final Map<String, Uri> urlForFamily = <String, Uri>{};
    for (final Map<String, dynamic> fontData in fontDatas) {
      if (fallbackFonts.contains(fontData['family'])) {
        final Uri uri = Uri.parse(fontData['files']['regular'] as String)
            .replace(scheme: 'https');
        urlForFamily[fontData['family'] as String] = uri;
      }
    }
    final Map<String, String> charsetForFamily = <String, String>{};
    final io.Directory fontDir = await io.Directory.systemTemp.createTemp('flutter_fallback_fonts');
    print('Downloading fonts into temp directory: ${fontDir.path}');
    final AccumulatorSink<crypto.Digest> hashSink = AccumulatorSink<crypto.Digest>();
    final ByteConversionSink hasher = crypto.sha256.startChunkedConversion(hashSink);
    for (final String family in fallbackFonts) {
      print('Downloading $family...');
      final Uri? uri = urlForFamily[family];
      if (uri == null) {
        throw ToolExit('Unable to determine URL to download $family. '
            'Check if it is still hosted on Google Fonts.');
      }
      final http.Response fontResponse = await client.get(uri);
      if (fontResponse.statusCode != 200) {
        throw ToolExit('Failed to download font for $family');
      }
      final String urlString = uri.toString();
      if (!urlString.startsWith(expectedUrlPrefix)) {
        throw ToolExit('Unexpected url format received from Google Fonts API: $urlString.');
      }
      final String urlSuffix = urlString.substring(expectedUrlPrefix.length);
      final io.File fontFile =
          io.File(path.join(fontDir.path, urlSuffix));

      final Uint8List bodyBytes = fontResponse.bodyBytes;
      if (!_checkForLicenseAttribution(bodyBytes)) {
        throw ToolExit(
            'Expected license attribution not found in file: $urlString');
      }
      hasher.add(utf8.encode(urlSuffix));
      hasher.add(bodyBytes);

      await fontFile.create(recursive: true);
      await fontFile.writeAsBytes(bodyBytes, flush: true);
      final io.ProcessResult fcQueryResult =
          await io.Process.run('fc-query', <String>[
        '--format=%{charset}',
        '--',
        fontFile.path,
      ]);
      final String encodedCharset = fcQueryResult.stdout as String;
      charsetForFamily[family] = encodedCharset;
    }

    final StringBuffer sb = StringBuffer();

    final List<_Font> fonts = <_Font>[];

    for (final String family in fallbackFonts) {
      final List<int> starts = <int>[];
      final List<int> ends = <int>[];
      final String charset = charsetForFamily[family]!;
      for (final String range in charset.split(' ')) {
        // Range is one hexadecimal number or two, separated by `-`.
        final List<String> parts = range.split('-');
        if (parts.length != 1 && parts.length != 2) {
          throw ToolExit('Malformed charset range "$range"');
        }
        final int first = int.parse(parts.first, radix: 16);
        final int last = int.parse(parts.last, radix: 16);
        starts.add(first);
        ends.add(last);
      }

      fonts.add(_Font(family, fonts.length, starts, ends));
    }

    final String fontSetsCode = _computeEncodedFontSets(fonts);

    sb.writeln('// Copyright 2013 The Flutter Authors. All rights reserved.');
    sb.writeln('// Use of this source code is governed by a BSD-style license '
        'that can be');
    sb.writeln('// found in the LICENSE file.');
    sb.writeln();
    sb.writeln('// DO NOT EDIT! This file is generated. See:');
    sb.writeln('// dev/roll_fallback_fonts.dart');
    sb.writeln("import 'noto_font.dart';");
    sb.writeln();
    sb.writeln('List<NotoFont> getFallbackFontList(bool useColorEmoji) => <NotoFont>[');

    for (final _Font font in fonts) {
      final String family = font.family;
      String enabledArgument = '';
      if (family == 'Noto Emoji') {
        enabledArgument = 'enabled: !useColorEmoji, ';
      }
      if (family == 'Noto Color Emoji') {
        enabledArgument = 'enabled: useColorEmoji, ';
      }
      final String urlString = urlForFamily[family]!.toString();
      if (!urlString.startsWith(expectedUrlPrefix)) {
        throw ToolExit(
            'Unexpected url format received from Google Fonts API: $urlString.');
      }
      final String urlSuffix = urlString.substring(expectedUrlPrefix.length);
      sb.writeln(" NotoFont('$family', $enabledArgument'$urlSuffix'),");
    }
    sb.writeln('];');
    sb.writeln();
    sb.write(fontSetsCode);

    final io.File fontDataFile = io.File(path.join(
      environment.webUiRootDir.path,
      'lib',
      'src',
      'engine',
      'font_fallback_data.dart',
    ));
    await fontDataFile.writeAsString(sb.toString());

    final io.File licenseFile = io.File(path.join(
      fontDir.path,
      'LICENSE.txt',
    ));
    const String licenseString = r'''
© Copyright 2015-2021 Google LLC. All Rights Reserved.

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
''';
    final List<int> licenseData = utf8.encode(licenseString);
    await licenseFile.create(recursive: true);
    await licenseFile.writeAsBytes(licenseData);
    hasher.add(licenseData);
    hasher.close();

    final crypto.Digest digest = hashSink.events.single;
    final String versionString = digest.toString();
    const String packageName = 'flutter/flutter_font_fallbacks';
    if (await cipdKnowsPackageVersion(
      package: packageName,
      versionTag: versionString)) {
        print('Package already exists with hash $versionString. Skipping upload');
    } else {
      print('Uploading fallback fonts to CIPD with hash $versionString');
      await uploadDirectoryToCipd(
        directory: fontDir,
        packageName: packageName,
        configFileName: 'cipd.flutter_font_fallbacks.yaml',
        description: 'A set of Noto fonts to fall back to for use in testing.',
        root: fontDir.path,
        version: versionString,
        isDryRun: isDryRun,
      );
    }

    print('Setting new fallback fonts deps version to $versionString');
    final String depFilePath = path.join(
      environment.engineSrcDir.path,
      'flutter',
      'DEPS',
    );
    await runProcess('gclient', <String>[
      'setdep',
      '--revision=src/third_party/google_fonts_for_unit_tests:$packageName@$versionString',
      '--deps-file=$depFilePath'
    ]);
  }
}

const List<String> fallbackFonts = <String>[
  'Noto Sans',
  'Noto Color Emoji',
  'Noto Emoji',
  'Noto Music',
  'Noto Sans Symbols',
  'Noto Sans Symbols 2',
  'Noto Sans Adlam',
  'Noto Sans Anatolian Hieroglyphs',
  'Noto Sans Arabic',
  'Noto Sans Armenian',
  'Noto Sans Avestan',
  'Noto Sans Balinese',
  'Noto Sans Bamum',
  'Noto Sans Bassa Vah',
  'Noto Sans Batak',
  'Noto Sans Bengali',
  'Noto Sans Bhaiksuki',
  'Noto Sans Brahmi',
  'Noto Sans Buginese',
  'Noto Sans Buhid',
  'Noto Sans Canadian Aboriginal',
  'Noto Sans Carian',
  'Noto Sans Caucasian Albanian',
  'Noto Sans Chakma',
  'Noto Sans Cham',
  'Noto Sans Cherokee',
  'Noto Sans Coptic',
  'Noto Sans Cuneiform',
  'Noto Sans Cypriot',
  'Noto Sans Deseret',
  'Noto Sans Devanagari',
  'Noto Sans Duployan',
  'Noto Sans Egyptian Hieroglyphs',
  'Noto Sans Elbasan',
  'Noto Sans Elymaic',
  'Noto Sans Georgian',
  'Noto Sans Glagolitic',
  'Noto Sans Gothic',
  'Noto Sans Grantha',
  'Noto Sans Gujarati',
  'Noto Sans Gunjala Gondi',
  'Noto Sans Gurmukhi',
  'Noto Sans HK',
  'Noto Sans Hanunoo',
  'Noto Sans Hatran',
  'Noto Sans Hebrew',
  'Noto Sans Imperial Aramaic',
  'Noto Sans Indic Siyaq Numbers',
  'Noto Sans Inscriptional Pahlavi',
  'Noto Sans Inscriptional Parthian',
  'Noto Sans JP',
  'Noto Sans Javanese',
  'Noto Sans KR',
  'Noto Sans Kaithi',
  'Noto Sans Kannada',
  'Noto Sans Kayah Li',
  'Noto Sans Kharoshthi',
  'Noto Sans Khmer',
  'Noto Sans Khojki',
  'Noto Sans Khudawadi',
  'Noto Sans Lao',
  'Noto Sans Lepcha',
  'Noto Sans Limbu',
  'Noto Sans Linear A',
  'Noto Sans Linear B',
  'Noto Sans Lisu',
  'Noto Sans Lycian',
  'Noto Sans Lydian',
  'Noto Sans Mahajani',
  'Noto Sans Malayalam',
  'Noto Sans Mandaic',
  'Noto Sans Manichaean',
  'Noto Sans Marchen',
  'Noto Sans Masaram Gondi',
  'Noto Sans Math',
  'Noto Sans Mayan Numerals',
  'Noto Sans Medefaidrin',
  'Noto Sans Meetei Mayek',
  'Noto Sans Meroitic',
  'Noto Sans Miao',
  'Noto Sans Modi',
  'Noto Sans Mongolian',
  'Noto Sans Mro',
  'Noto Sans Multani',
  'Noto Sans Myanmar',
  'Noto Sans NKo',
  'Noto Sans Nabataean',
  'Noto Sans New Tai Lue',
  'Noto Sans Newa',
  'Noto Sans Nushu',
  'Noto Sans Ogham',
  'Noto Sans Ol Chiki',
  'Noto Sans Old Hungarian',
  'Noto Sans Old Italic',
  'Noto Sans Old North Arabian',
  'Noto Sans Old Permic',
  'Noto Sans Old Persian',
  'Noto Sans Old Sogdian',
  'Noto Sans Old South Arabian',
  'Noto Sans Old Turkic',
  'Noto Sans Oriya',
  'Noto Sans Osage',
  'Noto Sans Osmanya',
  'Noto Sans Pahawh Hmong',
  'Noto Sans Palmyrene',
  'Noto Sans Pau Cin Hau',
  'Noto Sans Phags Pa',
  'Noto Sans Phoenician',
  'Noto Sans Psalter Pahlavi',
  'Noto Sans Rejang',
  'Noto Sans Runic',
  'Noto Sans SC',
  'Noto Sans Saurashtra',
  'Noto Sans Sharada',
  'Noto Sans Shavian',
  'Noto Sans Siddham',
  'Noto Sans Sinhala',
  'Noto Sans Sogdian',
  'Noto Sans Sora Sompeng',
  'Noto Sans Soyombo',
  'Noto Sans Sundanese',
  'Noto Sans Syloti Nagri',
  'Noto Sans Syriac',
  'Noto Sans TC',
  'Noto Sans Tagalog',
  'Noto Sans Tagbanwa',
  'Noto Sans Tai Le',
  'Noto Sans Tai Tham',
  'Noto Sans Tai Viet',
  'Noto Sans Takri',
  'Noto Sans Tamil',
  'Noto Sans Tamil Supplement',
  'Noto Sans Telugu',
  'Noto Sans Thaana',
  'Noto Sans Thai',
  'Noto Sans Tifinagh',
  'Noto Sans Tirhuta',
  'Noto Sans Ugaritic',
  'Noto Sans Vai',
  'Noto Sans Wancho',
  'Noto Sans Warang Citi',
  'Noto Sans Yi',
  'Noto Sans Zanabazar Square',
];

bool _checkForLicenseAttribution(Uint8List fontBytes) {
  final ByteData fontData = fontBytes.buffer.asByteData();
  final int codePointCount = fontData.lengthInBytes ~/ 2;
  const String attributionString =
      'This Font Software is licensed under the SIL Open Font License, Version 1.1.';
  for (int i = 0; i < codePointCount - attributionString.length; i++) {
    bool match = true;
    for (int j = 0; j < attributionString.length; j++) {
      if (fontData.getUint16((i + j) * 2) != attributionString.codeUnitAt(j)) {
        match = false;
        break;
      }
    }
    if (match) {
      return true;
    }
  }
  return false;
}

class _Font {
  _Font(this.family, this.index, this.starts, this.ends);

  final String family;
  final int index;
  final List<int> starts;
  final List<int> ends; // inclusive ends

  static int compare(_Font a, _Font b) => a.index.compareTo(b.index);

  String get shortName =>
      _shortName +
      String.fromCharCodes(
          '$index'.codeUnits.map((int ch) => ch - 48 + 0x2080));

  String get _shortName => family.startsWith('Noto Sans ')
      ? family.substring('Noto Sans '.length)
      : family;
}

/// The boundary of a range of a font.
class _Boundary {
  _Boundary(this.value, this.isStart, this.font);
  final int value; // inclusive start or exclusive end.
  final bool isStart;
  final _Font font;

  static int compare(_Boundary a, _Boundary b) => a.value.compareTo(b.value);
}

class _Range {
  _Range(this.start, this.end, this.fontSet);
  final int start;
  final int end;
  final _FontSet fontSet;

  @override
  String toString() {
    return '[${start.toRadixString(16)}, ${end.toRadixString(16)}]'
        ' (${end - start + 1})'
        ' ${fontSet.description()}';
  }
}

/// A canonical representative for a set of _Fonts. The fonts are stored in
/// order of increasing `_Font.index`.
class _FontSet {
  _FontSet(this.fonts);

  /// The number of [_Font]s in this set.
  int get length => fonts.length;

  /// The members of this set.
  final List<_Font> fonts;

  /// Number of unicode ranges that are supported by this set of fonts.
  int rangeCount = 0;

  /// The serialization order of this set. This index is assigned after building
  /// all the sets.
  late final int index;

  static int orderByDecreasingRangeCount(_FontSet a, _FontSet b) {
    final int r = b.rangeCount.compareTo(a.rangeCount);
    if (r != 0) {
      return r;
    }
    return orderByLexicographicFontIndexes(a, b);
  }

  static int orderByLexicographicFontIndexes(_FontSet a, _FontSet b) {
    for (int i = 0; i < a.length && i < b.length; i++) {
      final int r = _Font.compare(a.fonts[i], b.fonts[i]);
      if (r != 0) {
        return r;
      }
    }
    assert(a.length != b.length); // _FontSets are canonical.
    return a.length - b.length;
  }

  @override
  String toString() {
    return description();
  }

  String description() {
    return fonts.map((_Font font) => font.shortName).join(', ');
  }
}

/// A trie node [1] used to find the canonical _FontSet.
///
/// [1]: https://en.wikipedia.org/wiki/Trie
class _TrieNode {
  final Map<_Font, _TrieNode> _children = <_Font, _TrieNode>{};
  _FontSet? fontSet;

  /// Inserts a string of fonts into the trie and returns the trie node
  /// representing the string. [this] must be the root node of the trie.
  ///
  /// Inserting the same sequence again will traverse the same path through the
  /// trie and return the same node, canonicalizing the sequence to its
  /// representative node.
  _TrieNode insertSequenceAtRoot(Iterable<_Font> fonts) {
    _TrieNode node = this;
    for (final _Font font in fonts) {
      node = node._children[font] ??= _TrieNode();
    }
    return node;
  }
}

/// Computes the Dart source code for the encoded data structures used by the
/// fallback font selection algorithm.
///
/// The data structures allow the fallback font selection algorithm to quickly
/// determine which fonts support a given code point. The structures are
/// essentially a map from a code point to a set of fonts that support that code
/// point.
///
/// The universe of code points is partitioned into a set of subsets, or
/// components, where each component contains all the code points that are in
/// exactly the same set of fonts. A font can be considered to be a union of
/// some subset of the components and may share components with other fonts.  A
/// `_FontSet` is used to represent a component and the set of fonts that use
/// the component. One way to visualize this is as a Venn diagram. The fonts are
/// the overlapping circles and the components are the spaces between the lines.
///
/// The emitted data structures are
///
///  (1) A list of sets of fonts.
///  (2) A list of code point ranges mapping to an index of list (1).
///
/// Each set of fonts is represented as a list of font indexes. The indexes are
/// always increasing so the delta is stored. The stored value is biased by -1
/// (i.e.  `delta - 1`) since a delta is never less than 1. The deltas are STMR
/// encoded.
///
/// A code point with no fonts is mapped to an empty set of fonts. This allows
/// the list of code point ranges to be complete, covering every code
/// point. There are no gaps between ranges; instead there are some ranges that
/// map to the empty set. Each range is encoded as the size (number of code
/// points) in the range followed by the value which is the index of the
/// corresponding set in the list of sets.
///
///
/// STMR (Self terminating multiple radix) encoding
/// ---
///
/// This encoding is a minor adaptation of [VLQ encoding][1], using different
/// ranges of characters to represent continuing or terminating digits instead
/// of using a 'continuation' bit.
///
/// The separators between the numbers can be a significant proportion of the
/// number of characters needed to encode a sequence of numbers as a string.
/// Instead values are encoded with two kinds of digits: prefix digits and
/// terminating digits. Each kind of digit uses a different set of characters,
/// and the radix (number of digit characters) can differ between the different
/// kinds of digit.  Lets say we use decimal digits `0`..`9` for prefix digits
/// and `A`..`Z` as terminating digits.
///
///     M = ('M' - 'A') = 12
///     38M = (3 * 10 + 8) * 26 + 12 = 38 * 26 + 12 = 1000
///
/// Choosing a large terminating radix is especially effective when most of the
/// encoded values are small, as is the case with delta-encoding.
///
/// There can be multiple terminating digit kinds to represent different sorts
/// of values. For the range table, the size uses a different terminating digit,
/// 'a'..'z'. This allows the very common size of 1 (accounting over a third of
/// the range sizes) to be omitted. A range is encoded as either
/// `<size><value>`, or `<value>` with an implicit size of 1.  Since the size 1
/// can be implicit, it is always implicit, and the stored sizes are biased by
/// -2.
///
/// | encoding | value | size |
/// | :---     | ---:  | ---: |
/// | A        | 0     | 1    |
/// | B        | 1     | 1    |
/// | 38M      | 1000  | 1    |
/// | aA       | 0     | 2    |
/// | bB       | 1     | 3    |
/// | zZ       | 25    | 27   |
/// | 1a1A     | 26    | 28   |
/// | 38a38M   | 1000  | 1002 |
///
/// STMR-encoded strings are decoded efficiently by a simple loop that updates
/// the current value and performs some additional operation for a terminating
/// digit, e.g. recording the optional size, or creating a range.
///
/// [1]: https://en.wikipedia.org/wiki/Variable-length_quantity

String _computeEncodedFontSets(List<_Font> fonts) {
  final List<_Range> ranges = <_Range>[];
  final List<_FontSet> allSets = <_FontSet>[];

  {
    // The fonts have their supported code points provided as list of inclusive
    // [start, end] ranges. We want to intersect all of these ranges and find
    // the fonts that overlap each intersected range.
    //
    // It is easier to work with the boundaries of the ranges rather than the
    // ranges themselves. The boundaries of the intersected ranges is the union
    // of the boundaries of the individual font ranges.  We scan the boundaries
    // in increasing order, keeping track of the current set of fonts that are
    // in the current intersected range.  Each time the boundary value changes,
    // the current set of fonts is canonicalized and recorded.
    //
    // There has to be a wiki article for this algorithm but I didn't find one.
    final List<_Boundary> boundaries = <_Boundary>[];
    for (final _Font font in fonts) {
      for (final int start in font.starts) {
        boundaries.add(_Boundary(start, true, font));
      }
      for (final int end in font.ends) {
        boundaries.add(_Boundary(end + 1, false, font));
      }
    }
    boundaries.sort(_Boundary.compare);

    // The trie root represents the empty set of fonts.
    final _TrieNode trieRoot = _TrieNode();
    final Set<_Font> currentElements = <_Font>{};

    void newRange(int start, int end) {
      // Ensure we are using the canonical font order.
      final List<_Font> fonts = List<_Font>.of(currentElements)
        ..sort(_Font.compare);
      final _TrieNode node = trieRoot.insertSequenceAtRoot(fonts);
      final _FontSet fontSet = node.fontSet ??= _FontSet(fonts);
      if (fontSet.rangeCount == 0) {
        allSets.add(fontSet);
      }
      fontSet.rangeCount++;
      final _Range range = _Range(start, end, fontSet);
      ranges.add(range);
    }

    int start = 0;
    for (final _Boundary boundary in boundaries) {
      final int value = boundary.value;
      if (value > start) {
        // Boundary has changed, record the pending range `[start, value - 1]`,
        // and start a new range at `value`. `value` must be > 0 to get here.
        newRange(start, value - 1);
        start = value;
      }
      if (boundary.isStart) {
        currentElements.add(boundary.font);
      } else {
        currentElements.remove(boundary.font);
      }
    }
    assert(currentElements.isEmpty);
    // Ensure the ranges cover the whole unicode code point space.
    if (start <= kMaxCodePoint) {
      newRange(start, kMaxCodePoint);
    }
  }

  print('${allSets.length} sets covering ${ranges.length} ranges');

  // Sort _FontSets by the number of ranges that map to that _FontSet, so that
  // _FontSets that are referenced from many ranges have smaller indexes.  This
  // makes the range table encoding smaller, by about half.
  allSets.sort(_FontSet.orderByDecreasingRangeCount);

  for (int i = 0; i < allSets.length; i++) {
    allSets[i].index = i;
  }

  final StringBuffer code = StringBuffer();

  final StringBuffer sb = StringBuffer();
  int totalEncodedLength = 0;

  void encode(int value, int radix, int firstDigitCode) {
    final int prefix = value ~/ radix;
    assert(kPrefixDigit0 == '0'.codeUnitAt(0) && kPrefixRadix == 10);
    if (prefix != 0) {
      sb.write(prefix);
    }
    sb.writeCharCode(firstDigitCode + value.remainder(radix));
  }

  for (final _FontSet fontSet in allSets) {
    int previousFontIndex = -1;
    for (final _Font font in fontSet.fonts) {
      final int fontIndexDelta = font.index - previousFontIndex;
      previousFontIndex = font.index;
      encode(fontIndexDelta - 1, kFontIndexRadix, kFontIndexDigit0);
    }
    if (fontSet != allSets.last) {
      sb.write(',');
    }
    final String fragment = sb.toString();
    sb.clear();
    totalEncodedLength += fragment.length;

    final int length = fontSet.fonts.length;
    code.write('    // #${fontSet.index}: $length font');
    if (length != 1) {
      code.write('s');
    }
    if (length > 0) {
      code.write(': ${fontSet.description()}');
    }
    code.writeln('.');

    code.writeln("    '$fragment'");
  }

  final StringBuffer declarations = StringBuffer();

  final int references =
      allSets.fold(0, (int sum, _FontSet set) => sum + set.length);
  declarations
    ..writeln('// ${allSets.length} unique sets of fonts'
        ' containing $references font references'
        ' encoded in $totalEncodedLength characters')
    ..writeln('const String encodedFontSets =')
    ..write(code)
    ..writeln('    ;');

  // Encode ranges.
  code.clear();
  totalEncodedLength = 0;

  for (final _Range range in ranges) {
    final int start = range.start;
    final int end = range.end;
    final int index = range.fontSet.index;
    final int size = end - start + 1;

    // Encode <size><index> or <index> for unit ranges.
    if (size >= 2) {
      encode(size - 2, kRangeSizeRadix, kRangeSizeDigit0);
    }
    encode(index, kRangeValueRadix, kRangeValueDigit0);

    final String encoding = sb.toString();
    sb.clear();
    totalEncodedLength += encoding.length;

    String description = start.toRadixString(16);
    if (end != start) {
      description = '$description-${end.toRadixString(16)}';
    }
    if (range.fontSet.fonts.isNotEmpty) {
      description = '${description.padRight(12)} #$index';
    }
    final String encodingText = "'$encoding'".padRight(10);
    code.writeln('    $encodingText // $description');
  }

  declarations
    ..writeln()
    ..writeln(
        '// ${ranges.length} ranges encoded in $totalEncodedLength characters')
    ..writeln('const String encodedFontSetRanges =')
    ..write(code)
    ..writeln('    ;');

  return declarations.toString();
}
