// 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 vm_service.VM fakeVM = vm_service.VM(
  isolates: <vm_service.IsolateRef>[fakeUnpausedIsolate],
  pid: 1,
  hostCPU: '',
  isolateGroups: <vm_service.IsolateGroupRef>[],
  targetCPU: '',
  startTime: 0,
  name: 'dart',
  architectureBits: 64,
  operatingSystem: '',
  version: '',
  systemIsolateGroups: <vm_service.IsolateGroupRef>[],
  systemIsolates: <vm_service.IsolateRef>[],
);

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