// 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,
        buildId: 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 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();
}
