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

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dwds/dwds.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/targets/shader_compiler.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/isolated/devfs_web.dart';
import 'package:flutter_tools/src/isolated/resident_web_runner.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_devtools_handler.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:flutter_tools/src/web/chrome.dart';
import 'package:flutter_tools/src/web/web_device.dart';
import 'package:package_config/package_config.dart';
import 'package:package_config/package_config_types.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/fake_vm_services.dart';

const List<VmServiceExpectation> kAttachLogExpectations =
    <VmServiceExpectation>[
  FakeVmServiceRequest(
    method: 'streamListen',
    args: <String, Object>{
      'streamId': 'Stdout',
    },
  ),
  FakeVmServiceRequest(
    method: 'streamListen',
    args: <String, Object>{
      'streamId': 'Stderr',
    },
  ),
];

const List<VmServiceExpectation> kAttachIsolateExpectations =
    <VmServiceExpectation>[
  FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{
    'streamId': 'Isolate',
  }),
  FakeVmServiceRequest(method: 'registerService', args: <String, Object>{
    'service': 'reloadSources',
    'alias': 'Flutter Tools',
  }),
  FakeVmServiceRequest(method: 'registerService', args: <String, Object>{
    'service': 'flutterVersion',
    'alias': 'Flutter Tools',
  }),
  FakeVmServiceRequest(method: 'registerService', args: <String, Object>{
    'service': 'flutterMemoryInfo',
    'alias': 'Flutter Tools',
  }),
  FakeVmServiceRequest(
    method: 'streamListen',
    args: <String, Object>{
      'streamId': 'Extension',
    },
  ),
];

const List<VmServiceExpectation> kAttachExpectations = <VmServiceExpectation>[
  ...kAttachLogExpectations,
  ...kAttachIsolateExpectations,
];

void main() {
  late FakeDebugConnection debugConnection;
  late FakeChromeDevice chromeDevice;
  late FakeAppConnection appConnection;
  late FakeFlutterDevice flutterDevice;
  late FakeWebDevFS webDevFS;
  late FakeResidentCompiler residentCompiler;
  late FakeChromeConnection chromeConnection;
  late FakeChromeTab chromeTab;
  late FakeWebServerDevice webServerDevice;
  late FakeDevice mockDevice;
  late FakeVmServiceHost fakeVmServiceHost;
  late FileSystem fileSystem;
  late ProcessManager processManager;
  late TestUsage testUsage;

  setUp(() {
    testUsage = TestUsage();
    fileSystem = MemoryFileSystem.test();
    processManager = FakeProcessManager.any();
    debugConnection = FakeDebugConnection();
    mockDevice = FakeDevice();
    appConnection = FakeAppConnection();
    webDevFS = FakeWebDevFS();
    residentCompiler = FakeResidentCompiler();
    chromeDevice = FakeChromeDevice();
    chromeConnection = FakeChromeConnection();
    chromeTab = FakeChromeTab('index.html');
    webServerDevice = FakeWebServerDevice();
    flutterDevice = FakeFlutterDevice()
      .._devFS = webDevFS
      ..device = mockDevice
      ..generator = residentCompiler;
    fileSystem.file('.packages').writeAsStringSync('\n');
  });

  void setupMocks() {
    fileSystem.file('pubspec.yaml').createSync();
    fileSystem.file('lib/main.dart').createSync(recursive: true);
    fileSystem.file('web/index.html').createSync(recursive: true);
    webDevFS.report = UpdateFSReport(success: true);
    debugConnection.fakeVmServiceHost = () => fakeVmServiceHost;
    webDevFS.result = ConnectionResult(
      appConnection,
      debugConnection,
      debugConnection.vmService,
    );
    debugConnection.uri = 'ws://127.0.0.1/abcd/';
    chromeConnection.tabs.add(chromeTab);
  }

  testUsingContext(
      'runner with web server device does not support debugging without --start-paused',
      () {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    flutterDevice.device = WebServerDevice(
      logger: BufferLogger.test(),
    );
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    expect(profileResidentWebRunner.debuggingEnabled, false);

    flutterDevice.device = chromeDevice;

    expect(residentWebRunner.debuggingEnabled, true);
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'runner with web server device supports debugging with --start-paused',
      () {
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    flutterDevice.device = WebServerDevice(
      logger: BufferLogger.test(),
    );
    final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions:
          DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
      ipv6: true,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    expect(profileResidentWebRunner.uri, webDevFS.baseUri);
    expect(profileResidentWebRunner.debuggingEnabled, true);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });
  testUsingContext('profile does not supportsServiceProtocol', () {
    final ResidentRunner residentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    flutterDevice.device = chromeDevice;
    final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
      ipv6: true,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    expect(profileResidentWebRunner.supportsServiceProtocol, false);
    expect(residentWebRunner.supportsServiceProtocol, true);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Can successfully run and connect to vmservice', () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    final DebugConnectionInfo debugConnectionInfo =
        await connectionInfoCompleter.future;

    expect(appConnection.ranMain, true);
    expect(logger.statusText,
        contains('Debug service listening on ws://127.0.0.1/abcd/'));
    expect(debugConnectionInfo.wsUri.toString(), 'ws://127.0.0.1/abcd/');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('WebRunner copies compiled app.dill to cache during startup',
      () async {
    final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(
      const BuildInfo(BuildMode.debug, null, treeShakeIcons: false),
    );
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, debuggingOptions: debuggingOptions);
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();

    residentWebRunner.artifactDirectory
        .childFile('app.dill')
        .writeAsStringSync('ABC');
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(
        await fileSystem
            .file(fileSystem.path.join('build', 'cache.dill'))
            .readAsString(),
        'ABC');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'WebRunner copies compiled app.dill to cache during startup with track-widget-creation',
      () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();

    residentWebRunner.artifactDirectory
        .childFile('app.dill')
        .writeAsStringSync('ABC');
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(
        await fileSystem
            .file(fileSystem.path.join('build', 'cache.dill.track.dill'))
            .readAsString(),
        'ABC');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  // Regression test for https://github.com/flutter/flutter/issues/60613
  testUsingContext(
      'ResidentWebRunner calls appFailedToStart if initial compilation fails',
      () async {
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fileSystem
        .file(globals.fs.path.join('lib', 'main.dart'))
        .createSync(recursive: true);
    webDevFS.report = UpdateFSReport();

    expect(await residentWebRunner.run(), 1);
    // Completing this future ensures that the daemon can exit correctly.
    expect(await residentWebRunner.waitForAppToFinish(), 1);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'Can successfully run without an index.html including status warning',
      () async {
    final BufferLogger logger = BufferLogger.test();
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    fileSystem.file(fileSystem.path.join('web', 'index.html')).deleteSync();
    final ResidentWebRunner residentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      stayResident: false,
      fileSystem: fileSystem,
      logger: logger,
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    expect(await residentWebRunner.run(), 0);
    expect(logger.statusText,
        contains('This application is not configured to build on the web'));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Can successfully run and disconnect with --no-resident',
      () async {
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    final ResidentRunner residentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      stayResident: false,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    expect(await residentWebRunner.run(), 0);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Listens to stdout and stderr streams before running main',
      () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachLogExpectations,
      FakeVmServiceStreamResponse(
        streamId: 'Stdout',
        event: vm_service.Event(
            timestamp: 0,
            kind: vm_service.EventStreams.kStdout,
            bytes: base64.encode(utf8.encode('THIS MESSAGE IS IMPORTANT'))),
      ),
      FakeVmServiceStreamResponse(
        streamId: 'Stderr',
        event: vm_service.Event(
            timestamp: 0,
            kind: vm_service.EventStreams.kStderr,
            bytes: base64.encode(utf8.encode('SO IS THIS'))),
      ),
      ...kAttachIsolateExpectations,
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(logger.statusText, contains('THIS MESSAGE IS IMPORTANT'));
    expect(logger.statusText, contains('SO IS THIS'));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Listens to extension events with structured errors',
      () async {
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: testLogger);
    final Map<String, String> extensionData = <String, String>{
      'test': 'data',
      'renderedErrorText': 'error text',
    };
    final Map<String, String> emptyExtensionData = <String, String>{
      'test': 'data',
      'renderedErrorText': '',
    };
    final Map<String, String> nonStructuredErrorData = <String, String>{
      'other': 'other stuff',
    };
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
      FakeVmServiceStreamResponse(
        streamId: 'Extension',
        event: vm_service.Event(
          timestamp: 0,
          extensionKind: 'Flutter.Error',
          extensionData: vm_service.ExtensionData.parse(extensionData),
          kind: vm_service.EventStreams.kExtension,
        ),
      ),
      // Empty error text should not break anything.
      FakeVmServiceStreamResponse(
        streamId: 'Extension',
        event: vm_service.Event(
          timestamp: 0,
          extensionKind: 'Flutter.Error',
          extensionData: vm_service.ExtensionData.parse(emptyExtensionData),
          kind: vm_service.EventStreams.kExtension,
        ),
      ),
      // This is not Flutter.Error kind data, so it should not be logged.
      FakeVmServiceStreamResponse(
        streamId: 'Extension',
        event: vm_service.Event(
          timestamp: 0,
          extensionKind: 'Other',
          extensionData: vm_service.ExtensionData.parse(nonStructuredErrorData),
          kind: vm_service.EventStreams.kExtension,
        ),
      ),
    ]);

    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    await null;

    expect(testLogger.statusText, contains('\nerror text'));
    expect(testLogger.statusText, isNot(contains('other stuff')));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Does not run main with --start-paused', () async {
    final ResidentRunner residentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions:
          DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
      ipv6: true,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();

    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(appConnection.ranMain, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Can hot reload after attaching', () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner = setUpResidentRunner(
      flutterDevice,
      logger: logger,
      systemClock: SystemClock.fixed(DateTime(2001)),
    );
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
      const FakeVmServiceRequest(
          method: 'hotRestart',
          jsonResponse: <String, Object>{
            'type': 'Success',
          }),
      const FakeVmServiceRequest(
        method: 'streamListen',
        args: <String, Object>{
          'streamId': 'Isolate',
        },
      ),
    ]);
    setupMocks();
    final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
    final Chromium chrome =
        Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
    chromiumLauncher.setInstance(chrome);

    flutterDevice.device = GoogleChromeDevice(
      fileSystem: fileSystem,
      chromiumLauncher: chromiumLauncher,
      logger: BufferLogger.test(),
      platform: FakePlatform(),
      processManager: FakeProcessManager.any(),
    );
    webDevFS.report = UpdateFSReport(success: true);

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    final DebugConnectionInfo debugConnectionInfo =
        await connectionInfoCompleter.future;

    expect(debugConnectionInfo, isNotNull);

    final OperationResult result = await residentWebRunner.restart();

    expect(logger.statusText, contains('Restarted application in'));
    expect(result.code, 0);
    expect(webDevFS.mainUri.toString(), contains('entrypoint.dart'));

    // ensure that analytics are sent.
    expect(testUsage.events, <TestUsageEvent>[
      TestUsageEvent('hot', 'restart',
          parameters: CustomDimensions.fromMap(<String, String>{
            'cd27': 'web-javascript',
            'cd28': '',
            'cd29': 'false',
            'cd30': 'true',
            'cd13': '0',
            'cd48': 'false'
          })),
    ]);
    expect(testUsage.timings, const <TestTimingEvent>[
      TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
    ]);
  }, overrides: <Type, Generator>{
    Usage: () => testUsage,
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Can hot restart after attaching', () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner = setUpResidentRunner(
      flutterDevice,
      logger: logger,
      systemClock: SystemClock.fixed(DateTime(2001)),
    );
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
      const FakeVmServiceRequest(
          method: 'hotRestart',
          jsonResponse: <String, Object>{
            'type': 'Success',
          }),
    ]);
    setupMocks();
    final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
    final Chromium chrome =
        Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
    chromiumLauncher.setInstance(chrome);

    flutterDevice.device = GoogleChromeDevice(
      fileSystem: fileSystem,
      chromiumLauncher: chromiumLauncher,
      logger: BufferLogger.test(),
      platform: FakePlatform(),
      processManager: FakeProcessManager.any(),
    );
    webDevFS.report = UpdateFSReport(success: true);

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    final OperationResult result =
        await residentWebRunner.restart(fullRestart: true);

    // Ensure that generated entrypoint is generated correctly.
    expect(webDevFS.mainUri, isNotNull);
    final String entrypointContents =
        fileSystem.file(webDevFS.mainUri).readAsStringSync();
    expect(entrypointContents, contains('// Flutter web bootstrap script'));
    expect(entrypointContents, contains("import 'dart:ui' as ui;"));
    expect(entrypointContents, contains('await ui.webOnlyWarmupEngine('));

    expect(logger.statusText, contains('Restarted application in'));
    expect(result.code, 0);

    // ensure that analytics are sent.
    expect(testUsage.events, <TestUsageEvent>[
      TestUsageEvent('hot', 'restart',
          parameters: CustomDimensions.fromMap(<String, String>{
            'cd27': 'web-javascript',
            'cd28': '',
            'cd29': 'false',
            'cd30': 'true',
            'cd13': '0',
            'cd48': 'false'
          })),
    ]);
    expect(testUsage.timings, const <TestTimingEvent>[
      TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
    ]);
  }, overrides: <Type, Generator>{
    Usage: () => testUsage,
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Can hot restart after attaching with web-server device',
      () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner = setUpResidentRunner(
      flutterDevice,
      logger: logger,
      systemClock: SystemClock.fixed(DateTime(2001)),
    );
    fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations);
    setupMocks();
    flutterDevice.device = webServerDevice;
    webDevFS.report = UpdateFSReport(success: true);

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    final OperationResult result =
        await residentWebRunner.restart(fullRestart: true);

    expect(logger.statusText, contains('Restarted application in'));
    expect(result.code, 0);

    // web-server device does not send restart analytics
    expect(testUsage.events, isEmpty);
    expect(testUsage.timings, isEmpty);
  }, overrides: <Type, Generator>{
    Usage: () => testUsage,
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('web resident runner is debuggable', () {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());

    expect(residentWebRunner.debuggingEnabled, true);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Exits when initial compile fails', () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    webDevFS.report = UpdateFSReport();

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));

    expect(await residentWebRunner.run(), 1);
    expect(testUsage.events, isEmpty);
    expect(testUsage.timings, isEmpty);
  }, overrides: <Type, Generator>{
    Usage: () => testUsage,
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'Faithfully displays stdout messages with leading/trailing spaces',
      () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachLogExpectations,
      FakeVmServiceStreamResponse(
        streamId: 'Stdout',
        event: vm_service.Event(
          timestamp: 0,
          kind: vm_service.EventStreams.kStdout,
          bytes: base64.encode(
            utf8.encode(
                '    This is a message with 4 leading and trailing spaces    '),
          ),
        ),
      ),
      ...kAttachIsolateExpectations,
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(
        logger.statusText,
        contains(
            '    This is a message with 4 leading and trailing spaces    '));
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Fails on compilation errors in hot restart', () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    webDevFS.report = UpdateFSReport();

    final OperationResult result =
        await residentWebRunner.restart(fullRestart: true);

    expect(result.code, 1);
    expect(result.message, contains('Failed to recompile application.'));
    expect(testUsage.events, isEmpty);
    expect(testUsage.timings, isEmpty);
  }, overrides: <Type, Generator>{
    Usage: () => testUsage,
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'Fails non-fatally on vmservice response error for hot restart',
      () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
      const FakeVmServiceRequest(
        method: 'hotRestart',
        jsonResponse: <String, Object>{
          'type': 'Failed',
        },
      ),
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    final OperationResult result = await residentWebRunner.restart();

    expect(result.code, 0);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Fails fatally on Vm Service error response', () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
      const FakeVmServiceRequest(
        method: 'hotRestart',
        // Failed response,
        errorCode: RPCErrorCodes.kInternalError,
      ),
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    final OperationResult result = await residentWebRunner.restart();

    expect(result.code, 1);
    expect(result.message, contains(RPCErrorCodes.kInternalError.toString()));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('printHelp without details shows hot restart help message',
      () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    residentWebRunner.printHelp(details: false);

    expect(logger.statusText, contains('To hot restart changes'));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('cleanup of resources is safe to call multiple times',
      () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    mockDevice.dds = DartDevelopmentService();
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    await residentWebRunner.exit();
    await residentWebRunner.exit();

    expect(debugConnection.didClose, false);
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('cleans up Chrome if tab is closed', () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
    ]);
    setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    final Future<int?> result = residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    );
    await connectionInfoCompleter.future;
    debugConnection.completer.complete();

    await result;
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Prints target and device name on run', () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachExpectations,
    ]);
    setupMocks();
    mockDevice.name = 'Chromez';
    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    expect(
        logger.statusText,
        contains(
          'Launching ${fileSystem.path.join('lib', 'main.dart')} on '
          'Chromez in debug mode',
        ));
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Sends launched app.webLaunchUrl event for Chrome device',
      () async {
    final BufferLogger logger = BufferLogger.test();
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
      ...kAttachLogExpectations,
      ...kAttachIsolateExpectations,
    ]);
    setupMocks();
    final FakeChromeConnection chromeConnection = FakeChromeConnection();
    final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
    final Chromium chrome =
        Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
    chromiumLauncher.setInstance(chrome);

    flutterDevice.device = GoogleChromeDevice(
      fileSystem: fileSystem,
      chromiumLauncher: chromiumLauncher,
      logger: logger,
      platform: FakePlatform(),
      processManager: FakeProcessManager.any(),
    );
    webDevFS.baseUri = Uri.parse('http://localhost:8765/app/');

    final FakeChromeTab chromeTab = FakeChromeTab('index.html');
    chromeConnection.tabs.add(chromeTab);

    final ResidentWebRunner runner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      fileSystem: fileSystem,
      logger: logger,
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(runner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    // Ensure we got the URL and that it was already launched.
    expect(
        logger.eventText,
        contains(json.encode(
          <String, Object>{
            'name': 'app.webLaunchUrl',
            'args': <String, Object>{
              'url': 'http://localhost:8765/app/',
              'launched': true,
            },
          },
        )));
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext(
      'Sends unlaunched app.webLaunchUrl event for Web Server device',
      () async {
    final BufferLogger logger = BufferLogger.test();
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    flutterDevice.device = WebServerDevice(
      logger: logger,
    );
    webDevFS.baseUri = Uri.parse('http://localhost:8765/app/');

    final ResidentWebRunner runner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      fileSystem: fileSystem,
      logger: logger,
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    final Completer<DebugConnectionInfo> connectionInfoCompleter =
        Completer<DebugConnectionInfo>();
    unawaited(runner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;

    // Ensure we got the URL and that it was not already launched.
    expect(
        logger.eventText,
        contains(json.encode(
          <String, Object>{
            'name': 'app.webLaunchUrl',
            'args': <String, Object>{
              'url': 'http://localhost:8765/app/',
              'launched': false,
            },
          },
        )));
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('ResidentWebRunner generates files when l10n.yaml exists', () async {
    fakeVmServiceHost =
        FakeVmServiceHost(requests: kAttachExpectations.toList());
    setupMocks();
    final ResidentRunner residentWebRunner = ResidentWebRunner(
      flutterDevice,
      flutterProject:
          FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
      debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      ipv6: true,
      stayResident: false,
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
      usage: globals.flutterUsage,
      systemClock: globals.systemClock,
    );

    // Create necessary files.
    globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
      .createSync(recursive: true);
    globals.fs.file(globals.fs.path.join('lib', 'l10n', 'app_en.arb'))
      ..createSync(recursive: true)
      ..writeAsStringSync('''
{
  "helloWorld": "Hello, World!",
  "@helloWorld": {
    "description": "Sample description"
  }
}''');
    globals.fs.file('l10n.yaml').createSync();
    globals.fs.file('pubspec.yaml').writeAsStringSync('''
flutter:
  generate: true
''');
    globals.fs.directory('.dart_tool')
      .childFile('package_config.json')
      ..createSync(recursive: true)
      ..writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "path_provider_linux",
      "rootUri": "../../../path_provider_linux",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''');
    expect(await residentWebRunner.run(), 0);
    final File generatedLocalizationsFile = globals.fs.directory('.dart_tool')
      .childDirectory('flutter_gen')
      .childDirectory('gen_l10n')
      .childFile('app_localizations.dart');
    expect(generatedLocalizationsFile.existsSync(), isTrue);
    // Completing this future ensures that the daemon can exit correctly.
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  // While this file should be ignored on web, generating it here will cause a
  // perf regression in hot restart.
  testUsingContext('Does not generate dart_plugin_registrant.dart', () async {
    // Create necessary files for [DartPluginRegistrantTarget]
    final File packageConfig =
        globals.fs.directory('.dart_tool').childFile('package_config.json');
    packageConfig.createSync(recursive: true);
    packageConfig.writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "path_provider_linux",
      "rootUri": "../../../path_provider_linux",
      "packageUri": "lib/",
      "languageVersion": "2.12"
    }
  ]
}
''');
    // Start with a dart_plugin_registrant.dart file.
    globals.fs
        .directory('.dart_tool')
        .childDirectory('flutter_build')
        .childFile('dart_plugin_registrant.dart')
        .createSync(recursive: true);

    final FlutterProject project =
        FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);

    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    await residentWebRunner.runSourceGenerators();

    // dart_plugin_registrant.dart should be untouched, indicating that its
    // generation didn't run. If it had run, the file would have been removed as
    // there are no plugins in the project.
    expect(project.dartPluginRegistrant.existsSync(), true);
    expect(project.dartPluginRegistrant.readAsStringSync(), '');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Successfully turns WebSocketException into ToolExit',
      () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    webDevFS.exception = const WebSocketException();

    await expectLater(residentWebRunner.run, throwsToolExit());
    expect(logger.errorText, contains('WebSocketException'));
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Successfully turns AppConnectionException into ToolExit',
      () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    webDevFS.exception = AppConnectionException('');

    await expectLater(residentWebRunner.run, throwsToolExit());
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Successfully turns ChromeDebugError into ToolExit',
      () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();

    webDevFS.exception = ChromeDebugException(<String, Object?>{
      'text': 'error',
    });

    await expectLater(residentWebRunner.run, throwsToolExit());
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Rethrows unknown Exception type from dwds', () async {
    final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    webDevFS.exception = Exception();

    await expectLater(residentWebRunner.run, throwsException);
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('Rethrows unknown Error type from dwds tooling', () async {
    final BufferLogger logger = BufferLogger.test();
    final ResidentRunner residentWebRunner =
        setUpResidentRunner(flutterDevice, logger: logger);
    fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
    setupMocks();
    webDevFS.exception = StateError('');

    await expectLater(residentWebRunner.run, throwsStateError);
    expect(fakeVmServiceHost.hasRemainingExpectations, false);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });
}

ResidentRunner setUpResidentRunner(
  FlutterDevice flutterDevice, {
  Logger? logger,
  SystemClock? systemClock,
  DebuggingOptions? debuggingOptions,
}) {
  return ResidentWebRunner(
    flutterDevice,
    flutterProject:
        FlutterProject.fromDirectoryTest(globals.fs.currentDirectory),
    debuggingOptions:
        debuggingOptions ?? DebuggingOptions.enabled(BuildInfo.debug),
    ipv6: true,
    usage: globals.flutterUsage,
    systemClock: systemClock ?? SystemClock.fixed(DateTime.now()),
    fileSystem: globals.fs,
    logger: logger ?? BufferLogger.test(),
    devtoolsHandler: createNoOpHandler,
  );
}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
class FakeWebServerDevice extends FakeDevice implements WebServerDevice {}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
class FakeDevice extends Fake implements Device {
  @override
  String name = 'FakeDevice';

  int count = 0;

  @override
  Future<String> get sdkNameAndVersion async => 'SDK Name and Version';

  @override
  late DartDevelopmentService dds;

  @override
  Future<LaunchResult> startApp(
    covariant ApplicationPackage? package, {
    String? mainPath,
    String? route,
    DebuggingOptions? debuggingOptions,
    Map<String, dynamic>? platformArgs,
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String? userIdentifier,
  }) async {
    return LaunchResult.succeeded();
  }

  @override
  Future<bool> stopApp(
    covariant ApplicationPackage? app, {
    String? userIdentifier,
  }) async {
    if (count > 0) {
      throw StateError('stopApp called more than once.');
    }
    count += 1;
    return true;
  }
}

class FakeDebugConnection extends Fake implements DebugConnection {
  late FakeVmServiceHost Function() fakeVmServiceHost;

  @override
  vm_service.VmService get vmService =>
      fakeVmServiceHost.call().vmService.service;

  @override
  late String uri;

  final Completer<void> completer = Completer<void>();
  bool didClose = false;

  @override
  Future<void> get onDone => completer.future;

  @override
  Future<void> close() async {
    didClose = true;
  }
}

class FakeAppConnection extends Fake implements AppConnection {
  bool ranMain = false;

  @override
  void runMain() {
    ranMain = true;
  }
}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
class FakeChromeDevice extends Fake implements ChromiumDevice {}

class FakeWipDebugger extends Fake implements WipDebugger {}

class FakeResidentCompiler extends Fake implements ResidentCompiler {
  @override
  Future<CompilerOutput> recompile(
    Uri mainUri,
    List<Uri>? invalidatedFiles, {
    required String outputPath,
    required PackageConfig packageConfig,
    required FileSystem fs,
    String? projectRootPath,
    bool suppressErrors = false,
    bool checkDartPluginRegistry = false,
    File? dartPluginRegistrant,
  }) async {
    return const CompilerOutput('foo.dill', 0, <Uri>[]);
  }

  @override
  void accept() {}

  @override
  void reset() {}

  @override
  Future<CompilerOutput> reject() async {
    return const CompilerOutput('foo.dill', 0, <Uri>[]);
  }

  @override
  void addFileSystemRoot(String root) {}
}

class FakeWebDevFS extends Fake implements WebDevFS {
  Object? exception;
  ConnectionResult? result;
  late UpdateFSReport report;

  Uri? mainUri;

  @override
  List<Uri> sources = <Uri>[];

  @override
  Uri baseUri = Uri.parse('http://localhost:12345');

  @override
  DateTime? lastCompiled = DateTime.now();

  @override
  PackageConfig? lastPackageConfig = PackageConfig.empty;

  @override
  Future<Uri> create() async {
    return baseUri;
  }

  @override
  Future<UpdateFSReport> update({
    required Uri mainUri,
    required ResidentCompiler generator,
    required bool trackWidgetCreation,
    required String pathToReload,
    required List<Uri> invalidatedFiles,
    required PackageConfig packageConfig,
    required String dillOutputPath,
    required DevelopmentShaderCompiler shaderCompiler,
    DevFSWriter? devFSWriter,
    String? target,
    AssetBundle? bundle,
    DateTime? firstBuildTime,
    bool bundleFirstUpload = false,
    bool fullRestart = false,
    String? projectRootPath,
    File? dartPluginRegistrant,
  }) async {
    this.mainUri = mainUri;
    return report;
  }

  @override
  Future<ConnectionResult?> connect(bool useDebugExtension, {VmServiceFactory vmServiceFactory = createVmServiceDelegate}) async {
    if (exception != null) {
      assert(exception is Exception || exception is Error);
      // ignore: only_throw_errors, exception is either Error or Exception here.
      throw exception!;
    }
    return result;
  }
}

class FakeChromeConnection extends Fake implements ChromeConnection {
  final List<ChromeTab> tabs = <ChromeTab>[];

  @override
  Future<ChromeTab> getTab(bool Function(ChromeTab tab) accept,
      {Duration? retryFor}) async {
    return tabs.firstWhere(accept);
  }

  @override
  Future<List<ChromeTab>> getTabs({Duration? retryFor}) async {
    return tabs;
  }
}

class FakeChromeTab extends Fake implements ChromeTab {
  FakeChromeTab(this.url);

  @override
  final String url;
  final FakeWipConnection connection = FakeWipConnection();

  @override
  Future<WipConnection> connect({Function? onError}) async {
    return connection;
  }
}

class FakeWipConnection extends Fake implements WipConnection {
  @override
  final WipDebugger debugger = FakeWipDebugger();
}

/// A test implementation of the [ChromiumLauncher] that launches a fixed instance.
class TestChromiumLauncher implements ChromiumLauncher {
  TestChromiumLauncher();

  bool _hasInstance = false;
  void setInstance(Chromium chromium) {
    _hasInstance = true;
    currentCompleter.complete(chromium);
  }

  @override
  Completer<Chromium> currentCompleter = Completer<Chromium>();

  @override
  bool canFindExecutable() {
    return true;
  }

  @override
  Future<Chromium> get connectedInstance => currentCompleter.future;

  @override
  String findExecutable() {
    return 'chrome';
  }

  @override
  bool get hasChromeInstance => _hasInstance;

  @override
  Future<Chromium> launch(
    String url, {
    bool headless = false,
    int? debugPort,
    bool skipCheck = false,
    Directory? cacheDir,
    List<String> webBrowserFlags = const <String>[],
  }) async {
    return currentCompleter.future;
  }

  @override
  Future<Chromium> connect(Chromium chrome, bool skipCheck) {
    return currentCompleter.future;
  }
}

class FakeFlutterDevice extends Fake implements FlutterDevice {
  Uri? testUri;
  UpdateFSReport report = UpdateFSReport(
    success: true,
    invalidatedSourcesCount: 1,
  );
  Exception? reportError;

  @override
  ResidentCompiler? generator;

  @override
  Stream<Uri?> get observatoryUris => Stream<Uri?>.value(testUri);

  @override
  DevelopmentShaderCompiler get developmentShaderCompiler => const FakeShaderCompiler();

  @override
  FlutterVmService? vmService;

  DevFS? _devFS;

  @override
  DevFS? get devFS => _devFS;

  @override
  set devFS(DevFS? value) {}

  @override
  Device? device;

  @override
  Future<void> stopEchoingDeviceLog() async {}

  @override
  Future<void> initLogReader() async {}

  @override
  Future<Uri?> setupDevFS(String fsName, Directory rootDirectory) async {
    return testUri;
  }

  @override
  Future<void> exitApps(
      {Duration timeoutDelay = const Duration(seconds: 10)}) async {}

  @override
  Future<void> connect({
    ReloadSources? reloadSources,
    Restart? restart,
    CompileExpression? compileExpression,
    GetSkSLMethod? getSkSLMethod,
    PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
    int? hostVmServicePort,
    int? ddsPort,
    bool disableServiceAuthCodes = false,
    bool enableDds = true,
    bool cacheStartupProfile = false,
    required bool allowExistingDdsInstance,
    bool? ipv6 = false,
  }) async {}

  @override
  Future<UpdateFSReport> updateDevFS({
    Uri? mainUri,
    String? target,
    AssetBundle? bundle,
    DateTime? firstBuildTime,
    bool bundleFirstUpload = false,
    bool bundleDirty = false,
    bool fullRestart = false,
    String? projectRootPath,
    String? pathToReload,
    String? dillOutputPath,
    List<Uri>? invalidatedFiles,
    PackageConfig? packageConfig,
    File? dartPluginRegistrant,
  }) async {
    if (reportError != null) {
      throw reportError!;
    }
    return report;
  }

  @override
  Future<void> updateReloadStatus(bool wasReloadSuccessful) async {}
}

class FakeShaderCompiler implements DevelopmentShaderCompiler {
  const FakeShaderCompiler();

  @override
  void configureCompiler(TargetPlatform? platform, { required bool enableImpeller }) { }

  @override
  Future<DevFSContent> recompileShader(DevFSContent inputShader) {
    throw UnimplementedError();
  }
}
