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

// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=123"
@Tags(<String>['no-shuffle'])

import 'dart:async';
import 'dart:convert';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

class TestServiceExtensionsBinding extends BindingBase
  with SchedulerBinding,
       ServicesBinding,
       GestureBinding,
       PaintingBinding,
       SemanticsBinding,
       RendererBinding,
       WidgetsBinding,
       TestDefaultBinaryMessengerBinding {

  final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};

  final Map<String, List<Map<String, dynamic>>> eventsDispatched = <String, List<Map<String, dynamic>>>{};

  @override
  @protected
  void registerServiceExtension({
    required String name,
    required ServiceExtensionCallback callback,
  }) {
    expect(extensions.containsKey(name), isFalse);
    extensions[name] = callback;
  }

  @override
  void postEvent(String eventKind, Map<String, dynamic> eventData) {
    getEventsDispatched(eventKind).add(eventData);
  }

  List<Map<String, dynamic>> getEventsDispatched(String eventKind) {
    return eventsDispatched.putIfAbsent(eventKind, () => <Map<String, dynamic>>[]);
  }

  Iterable<Map<String, dynamic>> getServiceExtensionStateChangedEvents(String extensionName) {
    return getEventsDispatched('Flutter.ServiceExtensionStateChanged')
      .where((Map<String, dynamic> event) => event['extension'] == extensionName);
  }

  Future<Map<String, dynamic>> testExtension(String name, Map<String, String> arguments) {
    expect(extensions.containsKey(name), isTrue);
    return extensions[name]!(arguments);
  }

  int reassembled = 0;
  bool pendingReassemble = false;
  @override
  Future<void> performReassemble() {
    reassembled += 1;
    pendingReassemble = true;
    return super.performReassemble();
  }

  bool frameScheduled = false;
  @override
  void scheduleFrame() {
    ensureFrameCallbacksRegistered();
    frameScheduled = true;
  }
  Future<void> doFrame() async {
    frameScheduled = false;
    binding.platformDispatcher.onBeginFrame?.call(Duration.zero);
    await flushMicrotasks();
    binding.platformDispatcher.onDrawFrame?.call();
    binding.platformDispatcher.onReportTimings?.call(<ui.FrameTiming>[]);
  }

  @override
  void scheduleForcedFrame() {
    expect(true, isFalse);
  }

  @override
  void scheduleWarmUpFrame() {
    expect(pendingReassemble, isTrue);
    pendingReassemble = false;
  }

  Future<void> flushMicrotasks() {
    final Completer<void> completer = Completer<void>();
    Timer.run(completer.complete);
    return completer.future;
  }
}

late TestServiceExtensionsBinding binding;

Future<Map<String, dynamic>> hasReassemble(Future<Map<String, dynamic>> pendingResult) async {
  bool completed = false;
  pendingResult.whenComplete(() { completed = true; });
  expect(binding.frameScheduled, isFalse);
  await binding.flushMicrotasks();
  expect(binding.frameScheduled, isTrue);
  expect(completed, isFalse);
  await binding.flushMicrotasks();
  await binding.doFrame();
  await binding.flushMicrotasks();
  expect(completed, isTrue);
  expect(binding.frameScheduled, isFalse);
  return pendingResult;
}

void main() {
  final List<String?> console = <String?>[];

  setUpAll(() async {
    binding = TestServiceExtensionsBinding()..scheduleFrame();
    expect(binding.frameScheduled, isTrue);

    // We need to test this service extension here because the result is true
    // after the first binding.doFrame() call.
    Map<String, dynamic> firstFrameResult;
    expect(binding.debugDidSendFirstFrameEvent, isFalse);
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, <String, String>{});
    expect(firstFrameResult, <String, String>{'enabled': 'false'});

    expect(binding.firstFrameRasterized, isFalse);
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, <String, String>{});
    expect(firstFrameResult, <String, String>{'enabled': 'false'});

    await binding.doFrame();

    expect(binding.debugDidSendFirstFrameEvent, isTrue);
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, <String, String>{});
    expect(firstFrameResult, <String, String>{'enabled': 'true'});

    expect(binding.firstFrameRasterized, isTrue);
    firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, <String, String>{});
    expect(firstFrameResult, <String, String>{'enabled': 'true'});

    expect(binding.frameScheduled, isFalse);

    expect(debugPrint, equals(debugPrintThrottled));
    debugPrint = (String? message, { int? wrapWidth }) {
      console.add(message);
    };
  });

  tearDownAll(() async {
    // See widget_inspector_test.dart for tests of the ext.flutter.inspector
    // service extensions included in this count.
    int widgetInspectorExtensionCount = 16;
    if (WidgetInspectorService.instance.isWidgetCreationTracked()) {
      // Some inspector extensions are only exposed if widget creation locations
      // are tracked.
      widgetInspectorExtensionCount += 2;
    }

    // The following service extensions are disabled in web:
    // 1. exit
    // 2. showPerformanceOverlay
    const int disabledExtensions = kIsWeb ? 2 : 0;

    // The expected number of registered service extensions in the Flutter
    // framework, excluding any that are for the widget inspector
    // (see widget_inspector_test.dart for tests of the ext.flutter.inspector
    // service extensions).
    const int serviceExtensionCount = 37;

    expect(binding.extensions.length, serviceExtensionCount + widgetInspectorExtensionCount - disabledExtensions);

    expect(console, isEmpty);
    debugPrint = debugPrintThrottled;
  });

  // The following list is alphabetical, one test per extension.

  test('Service extensions - debugAllowBanner', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(WidgetsApp.debugAllowBannerOverride, true);
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(WidgetsApp.debugAllowBannerOverride, true);
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(WidgetsApp.debugAllowBannerOverride, false);
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(WidgetsApp.debugAllowBannerOverride, false);
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(WidgetsApp.debugAllowBannerOverride, true);
    result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(WidgetsApp.debugAllowBannerOverride, true);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDumpApp', () async {
    final Map<String, dynamic> result = await binding.testExtension(WidgetsServiceExtensions.debugDumpApp.name, <String, String>{});

    expect(result, <String, dynamic>{
      'data': matches('TestServiceExtensionsBinding - DEBUG MODE\n<no tree currently mounted>'),
    });
  });

  test('Service extensions - debugDumpRenderTree', () async {
    await binding.doFrame();
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpRenderTree.name, <String, String>{});

    expect(result, <String, dynamic>{
      'data': matches(
        r'^'
        r'RenderView#[0-9a-f]{5}\n'
        r'   debug mode enabled - [a-zA-Z]+\n'
        r'   window size: Size\(2400\.0, 1800\.0\) \(in physical pixels\)\n'
        r'   device pixel ratio: 3\.0 \(physical pixels per logical pixel\)\n'
        r'   configuration: Size\(800\.0, 600\.0\) at 3\.0x \(in logical pixels\)\n'
        r'$',
      ),
    });
  });

  test('Service extensions - debugDumpLayerTree', () async {
    await binding.doFrame();
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpLayerTree.name, <String, String>{});

    expect(result, <String, dynamic>{
      'data': matches(
        r'^'
        r'TransformLayer#[0-9a-f]{5}\n'
        r'   owner: RenderView#[0-9a-f]{5}\n'
        r'   creator: RenderView\n'
        r'   engine layer: (TransformEngineLayer|PersistedTransform)#[0-9a-f]{5}\n'
        r'   handles: 1\n'
        r'   offset: Offset\(0\.0, 0\.0\)\n'
        r'   transform:\n'
        r'     \[0] 3\.0,0\.0,0\.0,0\.0\n'
        r'     \[1] 0\.0,3\.0,0\.0,0\.0\n'
        r'     \[2] 0\.0,0\.0,1\.0,0\.0\n'
        r'     \[3] 0\.0,0\.0,0\.0,1\.0\n'
        r'$',
      ),
    });
  });

  test('Service extensions - debugDumpSemanticsTreeInTraversalOrder', () async {
    await binding.doFrame();
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInTraversalOrder.name, <String, String>{});

    expect(result, <String, String>{
      'data': 'Semantics not generated.\n'
        'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
        'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
        'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
    });
  });

  test('Service extensions - debugDumpSemanticsTreeInInverseHitTestOrder', () async {
    await binding.doFrame();
    final Map<String, dynamic> result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInInverseHitTestOrder.name, <String, String>{});

    expect(result, <String, String>{
      'data': 'Semantics not generated.\n'
        'For performance reasons, the framework only generates semantics when asked to do so by the platform.\n'
        'Usually, platforms only ask for semantics when assistive technologies (like screen readers) are running.\n'
        'To generate semantics, try turning on an assistive technology (like VoiceOver or TalkBack) on your device.'
    });
  });

  test('Service extensions - debugPaint', () async {
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.debugPaint');
    Map<String, dynamic> extensionChangedEvent;
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugPaintSizeEnabled, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintSizeEnabled, false);
    expect(extensionChangedEvents, isEmpty);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugPaintSizeEnabled, true);
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
    expect(extensionChangedEvent['value'], 'true');
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugPaintSizeEnabled, true);
    expect(extensionChangedEvents.length, 1);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintSizeEnabled, false);
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint');
    expect(extensionChangedEvent['value'], 'false');
    result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintSizeEnabled, false);
    expect(extensionChangedEvents.length, 2);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugPaintBaselinesEnabled', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugPaintBaselinesEnabled, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintBaselinesEnabled, false);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugPaintBaselinesEnabled, true);
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugPaintBaselinesEnabled, true);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintBaselinesEnabled, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugPaintBaselinesEnabled, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - invertOversizedImages', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugInvertOversizedImages, false);
    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);
    expect(binding.frameScheduled, isFalse);

    pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugInvertOversizedImages, true);

    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugInvertOversizedImages, true);
    expect(binding.frameScheduled, isFalse);

    pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);

    result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugInvertOversizedImages, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileWidgetBuilds', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabled, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabled, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabled, true);

    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabled, true);

    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabled, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabled, false);

    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileUserWidgetBuilds', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabledUserWidgets, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabledUserWidgets, true);

    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileBuildsEnabledUserWidgets, true);

    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

    result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileBuildsEnabledUserWidgets, false);

    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileRenderObjectPaints', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileBuildsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfilePaintsEnabled, true);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfilePaintsEnabled, true);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfilePaintsEnabled, false);

    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - profileRenderObjectLayouts', () async {
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(debugProfileLayoutsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileLayoutsEnabled, true);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugProfileLayoutsEnabled, true);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

    result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugProfileLayoutsEnabled, false);

    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - evict', () async {
    Map<String, dynamic> result;
    bool completed;

    completed = false;
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
      expect(utf8.decode(message!.buffer.asUint8List()), 'test');
      completed = true;
      return ByteData(5); // 0x0000000000
    });
    bool data;
    data = await rootBundle.loadStructuredData<bool>('test', (String value) async {
      expect(value, '\x00\x00\x00\x00\x00');
      return true;
    });
    expect(data, isTrue);
    expect(completed, isTrue);
    completed = false;
    data = await rootBundle.loadStructuredData('test', (String value) async {
      throw Error();
    });
    expect(data, isTrue);
    expect(completed, isFalse);
    result = await binding.testExtension(ServicesServiceExtensions.evict.name, <String, String>{'value': 'test'});
    expect(result, <String, String>{'value': ''});
    expect(completed, isFalse);
    data = await rootBundle.loadStructuredData<bool>('test', (String value) async {
      expect(value, '\x00\x00\x00\x00\x00');
      return false;
    });
    expect(data, isFalse);
    expect(completed, isTrue);
    TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
  });

  test('Service extensions - exit', () async {
    // no test for _calling_ 'exit', because that should terminate the process!
    // Not expecting extension to be available for web platform.
    expect(binding.extensions.containsKey(FoundationServiceExtensions.exit.name), !isBrowser);
  });

  test('Service extensions - platformOverride', () async {
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.platformOverride');
    Map<String, dynamic> extensionChangedEvent;
    Map<String, dynamic> result;

    expect(binding.reassembled, 0);
    expect(defaultTargetPlatform, TargetPlatform.android);
    result = await binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{});
    expect(result, <String, String>{'value': 'android'});
    expect(defaultTargetPlatform, TargetPlatform.android);
    expect(extensionChangedEvents, isEmpty);
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'iOS'}));
    expect(result, <String, String>{'value': 'iOS'});
    expect(binding.reassembled, 1);
    expect(defaultTargetPlatform, TargetPlatform.iOS);
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'iOS');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'macOS'}));
    expect(result, <String, String>{'value': 'macOS'});
    expect(binding.reassembled, 2);
    expect(defaultTargetPlatform, TargetPlatform.macOS);
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'macOS');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'android'}));
    expect(result, <String, String>{'value': 'android'});
    expect(binding.reassembled, 3);
    expect(defaultTargetPlatform, TargetPlatform.android);
    expect(extensionChangedEvents.length, 3);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'fuchsia'}));
    expect(result, <String, String>{'value': 'fuchsia'});
    expect(binding.reassembled, 4);
    expect(defaultTargetPlatform, TargetPlatform.fuchsia);
    expect(extensionChangedEvents.length, 4);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'fuchsia');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'default'}));
    expect(result, <String, String>{'value': 'android'});
    expect(binding.reassembled, 5);
    expect(defaultTargetPlatform, TargetPlatform.android);
    expect(extensionChangedEvents.length, 5);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'iOS'}));
    expect(result, <String, String>{'value': 'iOS'});
    expect(binding.reassembled, 6);
    expect(defaultTargetPlatform, TargetPlatform.iOS);
    expect(extensionChangedEvents.length, 6);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'iOS');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'linux'}));
    expect(result, <String, String>{'value': 'linux'});
    expect(binding.reassembled, 7);
    expect(defaultTargetPlatform, TargetPlatform.linux);
    expect(extensionChangedEvents.length, 7);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'linux');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'windows'}));
    expect(result, <String, String>{'value': 'windows'});
    expect(binding.reassembled, 8);
    expect(defaultTargetPlatform, TargetPlatform.windows);
    expect(extensionChangedEvents.length, 8);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'windows');
    result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, <String, String>{'value': 'bogus'}));
    expect(result, <String, String>{'value': 'android'});
    expect(binding.reassembled, 9);
    expect(defaultTargetPlatform, TargetPlatform.android);
    expect(extensionChangedEvents.length, 9);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride');
    expect(extensionChangedEvent['value'], 'android');
    binding.reassembled = 0;
  });

  test('Service extensions - repaintRainbow', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugRepaintRainbowEnabled, false);
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugRepaintRainbowEnabled, false);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugRepaintRainbowEnabled, true);
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugRepaintRainbowEnabled, true);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{'enabled': 'false'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(completed, false);
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugRepaintRainbowEnabled, false);
    result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugRepaintRainbowEnabled, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDisableClipLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisableClipLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableClipLayers, true);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableClipLayers, true);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableClipLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDisablePhysicalShapeLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisablePhysicalShapeLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisablePhysicalShapeLayers, true);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisablePhysicalShapeLayers, true);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisablePhysicalShapeLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - debugDisableOpacityLayers', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    expect(binding.frameScheduled, isFalse);
    expect(debugDisableOpacityLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{'enabled': 'true'});
    completed = false;
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, isFalse);
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, isTrue);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableOpacityLayers, true);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(debugDisableOpacityLayers, true);
    expect(binding.frameScheduled, isFalse);
    pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{'enabled': 'false'});
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    await binding.doFrame();
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
    result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(debugDisableOpacityLayers, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - reassemble', () async {
    Map<String, dynamic> result;
    Future<Map<String, dynamic>> pendingResult;
    bool completed;

    completed = false;
    expect(binding.reassembled, 0);
    pendingResult = binding.testExtension(FoundationServiceExtensions.reassemble.name, <String, String>{});
    pendingResult.whenComplete(() { completed = true; });
    await binding.flushMicrotasks();
    expect(binding.frameScheduled, isTrue);
    expect(completed, false);
    await binding.flushMicrotasks();
    await binding.doFrame();
    await binding.flushMicrotasks();
    expect(completed, true);
    expect(binding.frameScheduled, isFalse);
    result = await pendingResult;
    expect(result, <String, String>{});
    expect(binding.reassembled, 1);
  });

  test('Service extensions - showPerformanceOverlay', () async {
    Map<String, dynamic> result;

    // The performance overlay service extension is disabled on the web.
    if (kIsWeb) {
      expect(binding.extensions.containsKey(WidgetsServiceExtensions.showPerformanceOverlay.name), isFalse);
      return;
    }

    expect(binding.frameScheduled, isFalse);
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{'enabled': 'true'});
    expect(result, <String, String>{'enabled': 'true'});
    expect(WidgetsApp.showPerformanceOverlayOverride, true);
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'true'});
    expect(WidgetsApp.showPerformanceOverlayOverride, true);
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{'enabled': 'false'});
    expect(result, <String, String>{'enabled': 'false'});
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
    result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, <String, String>{});
    expect(result, <String, String>{'enabled': 'false'});
    expect(WidgetsApp.showPerformanceOverlayOverride, false);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - timeDilation', () async {
    final Iterable<Map<String, dynamic>> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.timeDilation');
    Map<String, dynamic> extensionChangedEvent;
    Map<String, dynamic> result;

    expect(binding.frameScheduled, isFalse);
    expect(timeDilation, 1.0);
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
    expect(timeDilation, 1.0);
    expect(extensionChangedEvents, isEmpty);
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{SchedulerServiceExtensions.timeDilation.name: '100.0'});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 100.0.toString()});
    expect(timeDilation, 100.0);
    expect(extensionChangedEvents.length, 1);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.${SchedulerServiceExtensions.timeDilation.name}');
    expect(extensionChangedEvent['value'], 100.0.toString());
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 100.0.toString()});
    expect(timeDilation, 100.0);
    expect(extensionChangedEvents.length, 1);
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{SchedulerServiceExtensions.timeDilation.name: '1.0'});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
    expect(timeDilation, 1.0);
    expect(extensionChangedEvents.length, 2);
    extensionChangedEvent = extensionChangedEvents.last;
    expect(extensionChangedEvent['extension'], 'ext.flutter.${SchedulerServiceExtensions.timeDilation.name}');
    expect(extensionChangedEvent['value'], 1.0.toString());
    result = await binding.testExtension(SchedulerServiceExtensions.timeDilation.name, <String, String>{});
    expect(result, <String, String>{SchedulerServiceExtensions.timeDilation.name: 1.0.toString()});
    expect(timeDilation, 1.0);
    expect(extensionChangedEvents.length, 2);
    expect(binding.frameScheduled, isFalse);
  });

  test('Service extensions - brightnessOverride', () async {
    Map<String, dynamic> result;
    result = await binding.testExtension(FoundationServiceExtensions.brightnessOverride.name, <String, String>{});
    final String brightnessValue = result['value'] as String;

    expect(brightnessValue, 'Brightness.light');
  });

  test('Service extensions - activeDevToolsServerAddress', () async {
    Map<String, dynamic> result;
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{});
    String serverAddress = result['value'] as String;
    expect(serverAddress, '');
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{'value': 'http://127.0.0.1:9101'});
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:9101');
    result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, <String, String>{'value': 'http://127.0.0.1:9102'});
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:9102');
  });

  test('Service extensions - connectedVmServiceUri', () async {
    Map<String, dynamic> result;
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{});
    String serverAddress = result['value'] as String;
    expect(serverAddress, '');
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{'value': 'http://127.0.0.1:54669/kMUMseKAnog=/'});
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:54669/kMUMseKAnog=/');
    result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, <String, String>{'value': 'http://127.0.0.1:54000/kMUMseKAnog=/'});
    serverAddress = result['value'] as String;
    expect(serverAddress, 'http://127.0.0.1:54000/kMUMseKAnog=/');
  });
}
