// 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:math' as math;

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'package:web_engine_tester/golden_tester.dart';

import '../common/test_initialization.dart';
import 'utils.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

const ui.Rect kDefaultRegion = ui.Rect.fromLTRB(0, 0, 100, 100);

void testMain() {
  group('Font fallbacks', () {
    setUpUnitTests(
      emulateTesterEnvironment: false,
      setUpTestViewDimensions: false,
    );

    setUp(() {
      debugDisableFontFallbacks = false;
    });

    /// Used to save and restore [ui.window.onPlatformMessage] after each test.
    ui.PlatformMessageCallback? savedCallback;

    final List<String> downloadedFontFamilies = <String>[];

    setUp(() {
      renderer.fontCollection.debugResetFallbackFonts();
      renderer.fontCollection.fontFallbackManager!.downloadQueue.fallbackFontUrlPrefixOverride = 'assets/fallback_fonts/';
      renderer.fontCollection.fontFallbackManager!.downloadQueue.debugOnLoadFontFamily
        = (String family) => downloadedFontFamilies.add(family);
      savedCallback = ui.window.onPlatformMessage;
    });

    tearDown(() {
      downloadedFontFamilies.clear();
      ui.window.onPlatformMessage = savedCallback;
    });

    test('Roboto is always a fallback font', () {
      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks, contains('Roboto'));
    });

    test('will download Noto Sans Arabic if Arabic text is added', () async {
      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks, <String>['Roboto']);

      // Creating this paragraph should cause us to start to download the
      // fallback font.
      ui.ParagraphBuilder pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.addText('مرحبا');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();

      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks,
          contains('Noto Sans Arabic'));

      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);

      pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.pushStyle(ui.TextStyle(fontSize: 32));
      pb.addText('مرحبا');
      pb.pop();
      final ui.Paragraph paragraph = pb.build();
      paragraph.layout(const ui.ParagraphConstraints(width: 1000));

      canvas.drawParagraph(paragraph, ui.Offset.zero);
      await drawPictureUsingCurrentRenderer(recorder.endRecording());

      await matchGoldenFile(
        'ui_font_fallback_arabic.png',
        region: kDefaultRegion,
      );
      // TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
    });

    test('will put the Noto Color Emoji font before other fallback fonts in the list',
        () async {
      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks, <String>['Roboto']);

      // Creating this paragraph should cause us to start to download the
      // Arabic fallback font.
      ui.ParagraphBuilder pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.addText('مرحبا');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();

      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks,
          <String>['Roboto', 'Noto Sans Arabic']);

      pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.pushStyle(ui.TextStyle(fontSize: 26));
      pb.addText('Hello 😊 مرحبا');
      pb.pop();
      final ui.Paragraph paragraph = pb.build();
      paragraph.layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();

      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks, <String>[
        'Roboto',
        'Noto Color Emoji',
        'Noto Sans Arabic',
      ]);
    });

    test('will download Noto Color Emojis and Noto Symbols if no matching Noto Font',
        () async {
      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks, <String>['Roboto']);

      // Creating this paragraph should cause us to start to download the
      // fallback font.
      ui.ParagraphBuilder pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.addText('Hello 😊');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();

      expect(renderer.fontCollection.fontFallbackManager!.globalFontFallbacks,
          contains('Noto Color Emoji'));

      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);

      pb = ui.ParagraphBuilder(
        ui.ParagraphStyle(),
      );
      pb.pushStyle(ui.TextStyle(fontSize: 26));
      pb.addText('Hello 😊');
      pb.pop();
      final ui.Paragraph paragraph = pb.build();
      paragraph.layout(const ui.ParagraphConstraints(width: 1000));

      canvas.drawParagraph(paragraph, ui.Offset.zero);
      await drawPictureUsingCurrentRenderer(recorder.endRecording());

      await matchGoldenFile(
        'ui_font_fallback_emoji.png',
        region: kDefaultRegion,
      );
      // TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
    });

    // Regression test for https://github.com/flutter/flutter/issues/75836
    // When we had this bug our font fallback resolution logic would end up in an
    // infinite loop and this test would freeze and time out.
    test(
        'Can find fonts for two adjacent unmatched code points from different fonts',
        () async {
      // Try rendering text that requires fallback fonts, initially before the fonts are loaded.

      ui.ParagraphBuilder pb = ui.ParagraphBuilder(ui.ParagraphStyle());
      pb.addText('ヽಠ');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();
      expect(
        downloadedFontFamilies,
        <String>[
          'Noto Sans SC',
          'Noto Sans Kannada',
        ],
      );

      // Do the same thing but this time with loaded fonts.
      downloadedFontFamilies.clear();
      pb = ui.ParagraphBuilder(ui.ParagraphStyle());
      pb.addText('ヽಠ');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));
      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();
      expect(downloadedFontFamilies, isEmpty);
    });

    test('can find glyph for 2/3 symbol', () async {
      // Try rendering text that requires fallback fonts, initially before the fonts are loaded.

      ui.ParagraphBuilder pb = ui.ParagraphBuilder(ui.ParagraphStyle());
      pb.addText('⅔');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();
      expect(
        downloadedFontFamilies,
        <String>[
          'Noto Sans',
        ],
      );

      // Do the same thing but this time with loaded fonts.
      downloadedFontFamilies.clear();
      pb = ui.ParagraphBuilder(ui.ParagraphStyle());
      pb.addText('⅔');
      pb.build().layout(const ui.ParagraphConstraints(width: 1000));

      await renderer.fontCollection.fontFallbackManager!.debugWhenIdle();
      expect(downloadedFontFamilies, isEmpty);
    });

    test('findMinimumFontsForCodePoints for all supported code points', () async {
      // Collect all supported code points from all fallback fonts in the Noto
      // font tree.
      final Set<String> testedFonts = <String>{};
      final Set<int> supportedUniqueCodePoints = <int>{};
      final IntervalTree<NotoFont> notoTree =
          renderer.fontCollection.fontFallbackManager!.notoTree;
      for (final NotoFont font in renderer.fontCollection.fontFallbackManager!.fallbackFonts) {
        testedFonts.add(font.name);
        for (final CodePointRange range in font.computeUnicodeRanges()) {
          for (int codePoint = range.start; codePoint < range.end; codePoint++) {
            supportedUniqueCodePoints.add(codePoint);
          }
        }
      }

      expect(
          supportedUniqueCodePoints.length, greaterThan(10000)); // sanity check
      expect(
          testedFonts,
          unorderedEquals(<String>{
            'Noto Sans',
            'Noto Color 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',
          }));

      // Construct random paragraphs out of supported code points.
      final math.Random random = math.Random(0);
      final List<int> supportedCodePoints = supportedUniqueCodePoints.toList()
        ..shuffle(random);
      const int paragraphLength = 3;
      const int totalTestSize = 1000;

      for (int batchStart = 0;
          batchStart < totalTestSize;
          batchStart += paragraphLength) {
        final int batchEnd =
            math.min(batchStart + paragraphLength, supportedCodePoints.length);
        final Set<int> codePoints = <int>{};
        for (int i = batchStart; i < batchEnd; i += 1) {
          codePoints.add(supportedCodePoints[i]);
        }
        final Set<NotoFont> fonts = <NotoFont>{};
        for (final int codePoint in codePoints) {
          final List<NotoFont> fontsForPoint = notoTree.intersections(codePoint);

          // All code points are extracted from the same tree, so there must
          // be at least one font supporting each code point
          expect(fontsForPoint, isNotEmpty);
          fonts.addAll(fontsForPoint);
        }

        try {
          renderer.fontCollection.fontFallbackManager!.findMinimumFontsForCodePoints(codePoints, fonts);
        } catch (e) {
          print(
            'findMinimumFontsForCodePoints failed:\n'
            '  Code points: ${codePoints.join(', ')}\n'
            '  Fonts: ${fonts.map((NotoFont f) => f.name).join(', ')}',
          );
          rethrow;
        }
      }
    });
  },
  // HTML renderer doesn't use the fallback font manager.
  skip: isHtml,
  timeout: const Timeout.factor(4));
}
