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

// @dart = 2.8

import 'dart:async';

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.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:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;

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

final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
  id: '1',
  pauseEvent: vm_service.Event(
    kind: vm_service.EventKind.kResume,
    timestamp: 0
  ),
  breakpoints: <vm_service.Breakpoint>[],
  exceptionPauseMode: null,
  extensionRPCs: <String>[],
  libraries: <vm_service.LibraryRef>[
    vm_service.LibraryRef(
      id: '1',
      uri: 'file:///hello_world/main.dart',
      name: '',
    ),
  ],
  livePorts: 0,
  name: 'test',
  number: '1',
  pauseOnExit: false,
  runnable: true,
  startTime: 0,
  isSystemIsolate: false,
  isolateFlags: <vm_service.IsolateFlag>[],
);

final FlutterView fakeFlutterView = FlutterView(
  id: 'a',
  uiIsolate: fakeUnpausedIsolate,
);

final FakeVmServiceRequest listViews = FakeVmServiceRequest(
  method: kListViewsMethod,
  jsonResponse: <String, Object>{
    'views': <Object>[
      fakeFlutterView.toJson(),
    ],
  },
);

void main() {
  testWithoutContext('keyboard input handling single help character', () async {
    final TestRunner testRunner = TestRunner();
    final Logger logger = BufferLogger.test();
    final Signals signals = Signals.test();
    final Terminal terminal = Terminal.test();
    final MemoryFileSystem fs = MemoryFileSystem.test();
    final ProcessInfo processInfo = ProcessInfo.test(fs);
    final TerminalHandler terminalHandler = TerminalHandler(
      testRunner,
      logger: logger,
      signals: signals,
      terminal: terminal,
      processInfo: processInfo,
      reportReady: false,
    );

    expect(testRunner.hasHelpBeenPrinted, false);
    await terminalHandler.processTerminalInput('h');
    expect(testRunner.hasHelpBeenPrinted, true);
  });

  testWithoutContext('keyboard input handling help character surrounded with newlines', () async {
    final TestRunner testRunner = TestRunner();
    final Logger logger = BufferLogger.test();
    final Signals signals = Signals.test();
    final Terminal terminal = Terminal.test();
    final MemoryFileSystem fs = MemoryFileSystem.test();
    final ProcessInfo processInfo = ProcessInfo.test(fs);
    final TerminalHandler terminalHandler = TerminalHandler(
      testRunner,
      logger: logger,
      signals: signals,
      terminal: terminal,
      processInfo: processInfo,
      reportReady: false,
    );

    expect(testRunner.hasHelpBeenPrinted, false);
    await terminalHandler.processTerminalInput('\nh\n');
    expect(testRunner.hasHelpBeenPrinted, true);
  });

  group('keycode verification, brought to you by the letter', () {
    testWithoutContext('a, can handle trailing newlines', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('a\n');

      expect(terminalHandler.lastReceivedCommand, 'a');
    });

    testWithoutContext('n, can handle trailing only newlines', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      await terminalHandler.processTerminalInput('\n\n');

      expect(terminalHandler.lastReceivedCommand, '');
    });

    testWithoutContext('a - debugToggleProfileWidgetBuilds', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.profileWidgetBuilds',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'enabled': 'false',
          },
         ),
        const FakeVmServiceRequest(
          method: 'ext.flutter.profileWidgetBuilds',
          args: <String, Object>{
            'isolateId': '1',
            'enabled': 'true',
          },
          jsonResponse: <String, Object>{
            'enabled': 'true',
          },
        ),
      ]);

      await terminalHandler.processTerminalInput('a');
    });

    testWithoutContext('a - debugToggleProfileWidgetBuilds with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.profileWidgetBuilds',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'enabled': 'false',
          },
        ),
        const FakeVmServiceRequest(
          method: 'ext.flutter.profileWidgetBuilds',
          args: <String, Object>{
            'isolateId': '1',
            'enabled': 'true',
          },
          jsonResponse: <String, Object>{
            'enabled': 'true',
          },
        ),
      ], web: true);

      await terminalHandler.processTerminalInput('a');
    });

    testWithoutContext('a - debugToggleProfileWidgetBuilds without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);

      await terminalHandler.processTerminalInput('a');
    });

    testWithoutContext('b - debugToggleBrightness', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.brightnessOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'Brightness.light',
          }
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.brightnessOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'Brightness.dark',
          },
          jsonResponse: <String, Object>{
            'value': 'Brightness.dark',
          }
        ),
      ]);
      await terminalHandler.processTerminalInput('b');

      expect(terminalHandler.logger.statusText, contains('Changed brightness to Brightness.dark'));
    });

    testWithoutContext('b - debugToggleBrightness with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.brightnessOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'Brightness.light',
          }
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.brightnessOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'Brightness.dark',
          },
          jsonResponse: <String, Object>{
            'value': 'Brightness.dark',
          }
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('b');

      expect(terminalHandler.logger.statusText, contains('Changed brightness to Brightness.dark'));
    });

    testWithoutContext('b - debugToggleBrightness without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);

      await terminalHandler.processTerminalInput('b');
    });

    testWithoutContext('d,D - detach', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
      await terminalHandler.processTerminalInput('d');

      expect(runner.calledDetach, true);
      runner.calledDetach = false;

      await terminalHandler.processTerminalInput('D');

      expect(runner.calledDetach, true);
    });

    testWithoutContext('h,H,? - printHelp', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
      await terminalHandler.processTerminalInput('h');

      expect(runner.calledPrintWithDetails, true);
      runner.calledPrintWithDetails = false;

      await terminalHandler.processTerminalInput('H');

      expect(runner.calledPrintWithDetails, true);
      runner.calledPrintWithDetails = false;

      await terminalHandler.processTerminalInput('?');

      expect(runner.calledPrintWithDetails, true);
    });

    testWithoutContext('i - debugToggleWidgetInspector', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.inspector.show',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ]);

      await terminalHandler.processTerminalInput('i');
    });

    testWithoutContext('i - debugToggleWidgetInspector with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.inspector.show',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ], web: true);

      await terminalHandler.processTerminalInput('i');
    });

    testWithoutContext('i - debugToggleWidgetInspector without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);

      await terminalHandler.processTerminalInput('i');
    });

    testWithoutContext('I - debugToggleInvertOversizedImages', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.invertOversizedImages',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('I');
    });

    testWithoutContext('I - debugToggleInvertOversizedImages with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.invertOversizedImages',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('I');
    });

    testWithoutContext('I - debugToggleInvertOversizedImages without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('I');
    });

    testWithoutContext('I - debugToggleInvertOversizedImages in profile mode is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], buildMode: BuildMode.profile);
      await terminalHandler.processTerminalInput('I');
    });

    testWithoutContext('L - debugDumpLayerTree', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpLayerTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'LAYER TREE',
          }
        ),
      ]);
      await terminalHandler.processTerminalInput('L');

      expect(terminalHandler.logger.statusText, contains('LAYER TREE'));
    });

    testWithoutContext('L - debugDumpLayerTree with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpLayerTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'LAYER TREE',
          }
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('L');

      expect(terminalHandler.logger.statusText, contains('LAYER TREE'));
    });

    testWithoutContext('L - debugDumpLayerTree with service protocol and profile mode is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], buildMode: BuildMode.profile);
      await terminalHandler.processTerminalInput('L');
    });

    testWithoutContext('L - debugDumpLayerTree without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('L');
    });

    testWithoutContext('o,O - debugTogglePlatform', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        // Request 1.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'iOS',
          },
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'fuchsia',
          },
          jsonResponse: <String, Object>{
            'value': 'fuchsia',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'android',
          },
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'iOS',
          },
          jsonResponse: <String, Object>{
            'value': 'iOS',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('o');
      await terminalHandler.processTerminalInput('O');

      expect(terminalHandler.logger.statusText, contains('Switched operating system to fuchsia'));
      expect(terminalHandler.logger.statusText, contains('Switched operating system to iOS'));
    });

    testWithoutContext('o,O - debugTogglePlatform with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        // Request 1.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'iOS',
          },
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'fuchsia',
          },
          jsonResponse: <String, Object>{
            'value': 'fuchsia',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'value': 'android',
          },
        ),
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.platformOverride',
          args: <String, Object>{
            'isolateId': '1',
            'value': 'iOS',
          },
          jsonResponse: <String, Object>{
            'value': 'iOS',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('o');
      await terminalHandler.processTerminalInput('O');

      expect(terminalHandler.logger.statusText, contains('Switched operating system to fuchsia'));
      expect(terminalHandler.logger.statusText, contains('Switched operating system to iOS'));
    });

    testWithoutContext('o,O - debugTogglePlatform without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('o');
      await terminalHandler.processTerminalInput('O');
    });

    testWithoutContext('p - debugToggleDebugPaintSizeEnabled', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugPaint',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('p');
    });

    testWithoutContext('p - debugToggleDebugPaintSizeEnabled with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugPaint',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('p');
    });

    testWithoutContext('p - debugToggleDebugPaintSizeEnabled without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('p');
    });

    testWithoutContext('P - debugTogglePerformanceOverlayOverride', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.showPerformanceOverlay',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('P');
    });

    testWithoutContext('P - debugTogglePerformanceOverlayOverride with web target is skipped ', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], web: true);
      await terminalHandler.processTerminalInput('P');
    });

    testWithoutContext('P - debugTogglePerformanceOverlayOverride without service protocol is skipped ', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('P');
    });

     testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'SEMANTICS DATA',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('S');

      expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
    });

    testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
          const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'SEMANTICS DATA',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('S');

      expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
    });

    testWithoutContext('S - debugDumpSemanticsTreeInTraversalOrder without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('S');
    });

    testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'SEMANTICS DATA',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('U');

      expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
    });

    testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
          const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'SEMANTICS DATA',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('U');

      expect(terminalHandler.logger.statusText, contains('SEMANTICS DATA'));
    });

    testWithoutContext('U - debugDumpSemanticsTreeInInverseHitTestOrder without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('U');
    });

    testWithoutContext('t,T - debugDumpRenderTree', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpRenderTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'RENDER DATA 1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpRenderTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'RENDER DATA 2',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('t');
      await terminalHandler.processTerminalInput('T');

      expect(terminalHandler.logger.statusText, contains('RENDER DATA 1'));
      expect(terminalHandler.logger.statusText, contains('RENDER DATA 2'));
    });

    testWithoutContext('t,T - debugDumpRenderTree with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpRenderTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'RENDER DATA 1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpRenderTree',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'RENDER DATA 2',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('t');
      await terminalHandler.processTerminalInput('T');

      expect(terminalHandler.logger.statusText, contains('RENDER DATA 1'));
      expect(terminalHandler.logger.statusText, contains('RENDER DATA 2'));
    });

    testWithoutContext('t,T - debugDumpRenderTree without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('t');
      await terminalHandler.processTerminalInput('T');
    });

    testWithoutContext('w,W - debugDumpApp', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpApp',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'WIDGET DATA 1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpApp',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'WIDGET DATA 2',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('w');
      await terminalHandler.processTerminalInput('W');

      expect(terminalHandler.logger.statusText, contains('WIDGET DATA 1'));
      expect(terminalHandler.logger.statusText, contains('WIDGET DATA 2'));
    });

    testWithoutContext('w,W - debugDumpApp with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpApp',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'WIDGET DATA 1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugDumpApp',
          args: <String, Object>{
            'isolateId': '1',
          },
          jsonResponse: <String, Object>{
            'data': 'WIDGET DATA 2',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('w');
      await terminalHandler.processTerminalInput('W');

      expect(terminalHandler.logger.statusText, contains('WIDGET DATA 1'));
      expect(terminalHandler.logger.statusText, contains('WIDGET DATA 2'));
    });

    testWithoutContext('v - launchDevToolsInBrowser', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
      final FakeResidentDevtoolsHandler devtoolsHandler = runner.residentDevtoolsHandler as FakeResidentDevtoolsHandler;

      expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isFalse);
      await terminalHandler.processTerminalInput('v');
      expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isTrue);
    });

    testWithoutContext('w,W - debugDumpApp without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('w');
      await terminalHandler.processTerminalInput('W');
    });

    testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugCheckElevationsEnabled',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugCheckElevationsEnabled',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ]);
      await terminalHandler.processTerminalInput('z');
      await terminalHandler.processTerminalInput('Z');
    });

    testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled with web target', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugCheckElevationsEnabled',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
        // Request 2.
        listViews,
        const FakeVmServiceRequest(
          method: 'ext.flutter.debugCheckElevationsEnabled',
          args: <String, Object>{
            'isolateId': '1',
          },
        ),
      ], web: true);
      await terminalHandler.processTerminalInput('z');
      await terminalHandler.processTerminalInput('Z');
    });

    testWithoutContext('z,Z - debugToggleDebugCheckElevationsEnabled without service protocol is skipped', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsServiceProtocol: false);
      await terminalHandler.processTerminalInput('z');
      await terminalHandler.processTerminalInput('Z');
    });

    testWithoutContext('q,Q - exit', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;
      await terminalHandler.processTerminalInput('q');

      expect(runner.calledExit, true);
      runner.calledExit = false;

      await terminalHandler.processTerminalInput('Q');

      expect(runner.calledExit, true);
    });

    testWithoutContext('r - hotReload unsupported', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsHotReload: false);
      await terminalHandler.processTerminalInput('r');
    });

    testWithoutContext('R - hotRestart unsupported', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], supportsRestart: false);
      await terminalHandler.processTerminalInput('R');
    });

    testWithoutContext('r - hotReload', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await terminalHandler.processTerminalInput('r');

      expect(runner.calledReload, true);
      expect(runner.calledRestart, false);
    });

    testWithoutContext('R - hotRestart', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[]);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await terminalHandler.processTerminalInput('R');

      expect(runner.calledReload, false);
      expect(runner.calledRestart, true);
    });

    testWithoutContext('r - hotReload with non-fatal error', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await terminalHandler.processTerminalInput('r');

      expect(runner.calledReload, true);
      expect(runner.calledRestart, false);
      expect(terminalHandler.logger.statusText, contains('Try again after fixing the above error(s).'));
    });

    testWithoutContext('R - hotRestart with non-fatal error', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await terminalHandler.processTerminalInput('R');

      expect(runner.calledReload, false);
      expect(runner.calledRestart, true);
      expect(terminalHandler.logger.statusText, contains('Try again after fixing the above error(s).'));
    });

    testWithoutContext('r - hotReload with fatal error', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await expectLater(() => terminalHandler.processTerminalInput('r'), throwsToolExit());

      expect(runner.calledReload, true);
      expect(runner.calledRestart, false);
    });

    testWithoutContext('R - hotRestart with fatal error', () async {
      final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
      final FakeResidentRunner runner = terminalHandler.residentRunner as FakeResidentRunner;

      await expectLater(() => terminalHandler.processTerminalInput('R'), throwsToolExit());

      expect(runner.calledReload, false);
      expect(runner.calledRestart, true);
    });
  });

  testWithoutContext('ResidentRunner clears the screen when it should', () async {
    final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[], reloadExitCode: 1, fatalReloadError: true);
    const String message = 'This should be cleared';

    expect(terminalHandler.logger.statusText, equals(''));
    terminalHandler.logger.printStatus(message);
    expect(terminalHandler.logger.statusText, equals('$message\n'));  // printStatus makes a newline

    await terminalHandler.processTerminalInput('c');
    expect(terminalHandler.logger.statusText, equals(''));
  });

  testWithoutContext('s, can take screenshot on debug device that supports screenshot', () async {
    final BufferLogger logger = BufferLogger.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
      listViews,
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'false',
        },
      ),
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'true',
        },
      ),
    ], logger: logger, supportsScreenshot: true);

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
  });

  testWithoutContext('s, can take screenshot on debug device that does not support screenshot', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
      listViews,
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'false',
        },
      ),
      FakeVmServiceRequest(
        method: '_flutter.screenshot',
        args: <String, Object>{},
        jsonResponse: <String, Object>{
          'screenshot': base64.encode(<int>[1, 2, 3, 4]),
        },
      ),
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'true',
        },
      ),
    ], logger: logger, fileSystem: fileSystem);

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
    expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
  });

  testWithoutContext('s, can take screenshot on debug web device that does not support screenshot', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(<FakeVmServiceRequest>[
      listViews,
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'false',
        },
      ),
      FakeVmServiceRequest(
        method: 'ext.dwds.screenshot',
        args: <String, Object>{},
        jsonResponse: <String, Object>{
          'data': base64.encode(<int>[1, 2, 3, 4]),
        },
      ),
      FakeVmServiceRequest(
        method: 'ext.flutter.debugAllowBanner',
        args: <String, Object>{
          'isolateId': fakeUnpausedIsolate.id,
          'enabled': 'true',
        },
      ),
    ], logger: logger, web: true, fileSystem: fileSystem);

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
    expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
  });

  testWithoutContext('s, can take screenshot on device that does not support service protocol', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[],
      logger: logger,
      supportsScreenshot: true,
      supportsServiceProtocol: false,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, contains('Screenshot written to flutter_01.png (0kB)'));
    expect(fileSystem.currentDirectory.childFile('flutter_01.png').readAsBytesSync(), <int>[1, 2, 3, 4]);
  });

  testWithoutContext('s, does not take a screenshot on a device that does not support screenshot or the service protocol', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[],
      logger: logger,
      supportsServiceProtocol: false,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, '\n');
    expect(fileSystem.currentDirectory.childFile('flutter_01.png'), isNot(exists));
  });

  testWithoutContext('s, does not take a screenshot on a web device that does not support screenshot or the service protocol', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[],
      logger: logger,
      supportsServiceProtocol: false,
      web: true,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.statusText, '\n');
    expect(fileSystem.currentDirectory.childFile('flutter_01.png'), isNot(exists));
  });

  testWithoutContext('s, bails taking screenshot on debug device if debugAllowBanner throws RpcError', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[
        listViews,
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'false',
          },
          // Failed response,
          errorCode: RPCErrorCodes.kInternalError,
        ),
      ],
      logger: logger,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.errorText, contains('Error'));
  });

  testWithoutContext('s, bails taking screenshot on debug device if flutter.screenshot throws RpcError, restoring banner', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[
        listViews,
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'false',
          },
        ),
        const FakeVmServiceRequest(
          method: '_flutter.screenshot',
          // Failed response,
          errorCode: RPCErrorCodes.kInternalError,
        ),
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'true',
          },
        ),
      ],
      logger: logger,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.errorText, contains('Error'));
  });

  testWithoutContext('s, bails taking screenshot on debug device if dwds.screenshot throws RpcError, restoring banner', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[
        listViews,
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'false',
          },
        ),
        const FakeVmServiceRequest(
          method: 'ext.dwds.screenshot',
          // Failed response,
          errorCode: RPCErrorCodes.kInternalError,
        ),
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'true',
          },
        ),
      ],
      logger: logger,
      web: true,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.errorText, contains('Error'));
  });

  testWithoutContext('s, bails taking screenshot on debug device if debugAllowBanner during second request', () async {
    final BufferLogger logger = BufferLogger.test();
    final FileSystem fileSystem = MemoryFileSystem.test();
    final TerminalHandler terminalHandler = setUpTerminalHandler(
      <FakeVmServiceRequest>[
        listViews,
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'false',
          },
        ),
        FakeVmServiceRequest(
          method: 'ext.flutter.debugAllowBanner',
          args: <String, Object>{
            'isolateId': fakeUnpausedIsolate.id,
            'enabled': 'true',
          },
          // Failed response,
          errorCode: RPCErrorCodes.kInternalError,
        ),
      ],
      logger: logger,
      supportsScreenshot: true,
      fileSystem: fileSystem,
    );

    await terminalHandler.processTerminalInput('s');

    expect(logger.errorText, contains('Error'));
  });

  testWithoutContext('pidfile creation', () {
    final BufferLogger testLogger = BufferLogger.test();
    final Signals signals = _TestSignals(Signals.defaultExitSignals);
    final Terminal terminal = Terminal.test();
    final MemoryFileSystem fs = MemoryFileSystem.test();
    final ProcessInfo processInfo = ProcessInfo.test(fs);
    final FakeResidentRunner residentRunner = FakeResidentRunner(
      FlutterDevice(FakeDevice(), buildInfo: BuildInfo.debug, generator: FakeResidentCompiler()),
      testLogger,
      fs,
    );
    residentRunner
      ..supportsRestart = true
      ..supportsServiceProtocol = true
      ..stayResident = true;

    const String filename = 'test.pid';
    final TerminalHandler terminalHandler = TerminalHandler(
      residentRunner,
      logger: testLogger,
      signals: signals,
      terminal: terminal,
      processInfo: processInfo,
      reportReady: false,
      pidFile: filename,
    );

    expect(fs.file(filename), isNot(exists));
    terminalHandler.setupTerminal();
    terminalHandler.registerSignalHandlers();
    expect(fs.file(filename), exists);
    terminalHandler.stop();
    expect(fs.file(filename),  isNot(exists));
  });
}

class FakeResidentRunner extends ResidentHandlers {
  FakeResidentRunner(FlutterDevice device, this.logger, this.fileSystem) : flutterDevices = <FlutterDevice>[device];

  bool calledDetach = false;
  bool calledPrint = false;
  bool calledExit = false;
  bool calledPrintWithDetails = false;
  bool calledReload = false;
  bool calledRestart = false;
  int reloadExitCode = 0;
  bool fatalReloadError = false;

  @override
  final Logger logger;

  @override
  final FileSystem fileSystem;

  @override
  final List<FlutterDevice> flutterDevices;

  @override
  bool canHotReload = true;

  @override
  bool hotMode = true;

  @override
  bool isRunningDebug = true;

  @override
  bool isRunningProfile = false;

  @override
  bool isRunningRelease = false;

  @override
  bool stayResident = true;

  @override
  bool supportsRestart = true;

  @override
  bool supportsServiceProtocol = true;

  @override
  bool supportsWriteSkSL = true;

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

  @override
  Future<void> detach() async {
    calledDetach = true;
  }

  @override
  Future<void> exit() async {
    calledExit = true;
  }

  @override
  void printHelp({bool details}) {
    if (details) {
      calledPrintWithDetails = true;
    } else {
      calledPrint = true;
    }
  }

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

  @override
  Future<OperationResult> restart({bool fullRestart = false, bool pause = false, String reason}) async {
    if (fullRestart && !supportsRestart) {
      throw StateError('illegal restart');
    }
    if (!fullRestart && !canHotReload) {
      throw StateError('illegal reload');
    }
    if (fullRestart) {
      calledRestart = true;
    } else {
      calledReload = true;
    }
    return OperationResult(reloadExitCode, '', fatal: fatalReloadError);
  }

  @override
  ResidentDevtoolsHandler get residentDevtoolsHandler => _residentDevtoolsHandler;
  final ResidentDevtoolsHandler _residentDevtoolsHandler = FakeResidentDevtoolsHandler();
}

class FakeResidentDevtoolsHandler extends Fake implements ResidentDevtoolsHandler {
  bool calledLaunchDevToolsInBrowser = false;

  @override
  bool launchDevToolsInBrowser({List<FlutterDevice> flutterDevices}) {
    return calledLaunchDevToolsInBrowser = 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 FakeDevice extends Fake implements Device {
  @override
  bool isSupported() => true;

  @override
  bool supportsScreenshot = false;

  @override
  String get name => 'Fake Device';

  @override
  Future<void> takeScreenshot(File file) async {
    if (!supportsScreenshot) {
      throw StateError('illegal screenshot attempt');
    }
    file.writeAsBytesSync(<int>[1, 2, 3, 4]);
  }

}

TerminalHandler setUpTerminalHandler(List<FakeVmServiceRequest> requests, {
  bool supportsRestart = true,
  bool supportsServiceProtocol = true,
  bool supportsHotReload = true,
  bool web = false,
  bool fatalReloadError = false,
  bool supportsScreenshot = false,
  int reloadExitCode = 0,
  BuildMode buildMode = BuildMode.debug,
  Logger logger,
  FileSystem fileSystem,
}) {
  final Logger testLogger = logger ?? BufferLogger.test();
  final Signals signals = Signals.test();
  final Terminal terminal = Terminal.test();
  final FileSystem localFileSystem = fileSystem ?? MemoryFileSystem.test();
  final ProcessInfo processInfo = ProcessInfo.test(MemoryFileSystem.test());
  final FlutterDevice device = FlutterDevice(
    FakeDevice()..supportsScreenshot = supportsScreenshot,
    buildInfo: BuildInfo(buildMode, '', treeShakeIcons: false),
    generator: FakeResidentCompiler(),
    targetPlatform: web
      ? TargetPlatform.web_javascript
      : TargetPlatform.android_arm,
  );
  device.vmService = FakeVmServiceHost(requests: requests).vmService;
  final FakeResidentRunner residentRunner = FakeResidentRunner(device, testLogger, localFileSystem)
    ..supportsServiceProtocol = supportsServiceProtocol
    ..supportsRestart = supportsRestart
    ..canHotReload = supportsHotReload
    ..fatalReloadError = fatalReloadError
    ..reloadExitCode = reloadExitCode;

  switch (buildMode) {
    case BuildMode.debug:
      residentRunner
        ..isRunningDebug = true
        ..isRunningProfile = false
        ..isRunningRelease = false;
      break;
    case BuildMode.profile:
      residentRunner
        ..isRunningDebug = false
        ..isRunningProfile = true
        ..isRunningRelease = false;
      break;
    case BuildMode.release:
      residentRunner
        ..isRunningDebug = false
        ..isRunningProfile = false
        ..isRunningRelease = true;
      break;
  }
  return TerminalHandler(
    residentRunner,
    logger: testLogger,
    signals: signals,
    terminal: terminal,
    processInfo: processInfo,
    reportReady: false,
  );
}

class FakeResidentCompiler extends Fake implements ResidentCompiler { }

class TestRunner extends Fake implements ResidentRunner {
  bool hasHelpBeenPrinted = false;
  String receivedCommand;

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

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

  @override
  void printHelp({ bool details }) {
    hasHelpBeenPrinted = true;
  }

  @override
  Future<int> run({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    bool enableDevTools = false,
    String route,
  }) async => null;

  @override
  Future<int> attach({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    bool allowExistingDdsInstance = false,
    bool enableDevTools = false,
    bool needsFullRestart = true,
  }) async => null;
}

class _TestSignals implements Signals {
  _TestSignals(this.exitSignals);

  final List<ProcessSignal> exitSignals;

  final Map<ProcessSignal, Map<Object, SignalHandler>> _handlersTable =
      <ProcessSignal, Map<Object, SignalHandler>>{};

  @override
  Object addHandler(ProcessSignal signal, SignalHandler handler) {
    final Object token = Object();
    _handlersTable.putIfAbsent(signal, () => <Object, SignalHandler>{})[token] = handler;
    return token;
  }

  @override
  Future<bool> removeHandler(ProcessSignal signal, Object token) async {
    if (!_handlersTable.containsKey(signal)) {
      return false;
    }
    if (!_handlersTable[signal].containsKey(token)) {
      return false;
    }
    _handlersTable[signal].remove(token);
    return true;
  }

  @override
  Stream<Object> get errors => _errors.stream;
  final StreamController<Object> _errors = StreamController<Object>();
}
