// 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 'dart:convert';

import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/fuchsia/amber_ctl.dart';
import 'package:flutter_tools/src/fuchsia/application_package.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_dev_finder.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_device.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_ffx.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_kernel_compiler.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_pm.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart';
import 'package:flutter_tools/src/fuchsia/tiles_ctl.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:vm_service/vm_service.dart' as vm_service;

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

final vm_service.Isolate fakeIsolate = vm_service.Isolate(
  id: '1',
  pauseEvent: vm_service.Event(
    kind: vm_service.EventKind.kResume,
    timestamp: 0
  ),
  breakpoints: <vm_service.Breakpoint>[],
  exceptionPauseMode: null,
  libraries: <vm_service.LibraryRef>[],
  livePorts: 0,
  name: 'wrong name',
  number: '1',
  pauseOnExit: false,
  runnable: true,
  startTime: 0,
  isSystemIsolate: false,
  isolateFlags: <vm_service.IsolateFlag>[],
);

void main() {
  group('fuchsia device', () {
    MemoryFileSystem memoryFileSystem;
    File sshConfig;

    setUp(() {
      memoryFileSystem = MemoryFileSystem.test();
      sshConfig = memoryFileSystem.file('ssh_config')..writeAsStringSync('\n');
    });

    testWithoutContext('stores the requested id and name', () {
      const String deviceId = 'e80::0000:a00a:f00f:2002/3';
      const String name = 'halfbaked';
      final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name);

      expect(device.id, deviceId);
      expect(device.name, name);
    });

    testWithoutContext('supports all runtime modes besides jitRelease', () {
      const String deviceId = 'e80::0000:a00a:f00f:2002/3';
      const String name = 'halfbaked';
      final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name);

      expect(device.supportsRuntimeMode(BuildMode.debug), true);
      expect(device.supportsRuntimeMode(BuildMode.profile), true);
      expect(device.supportsRuntimeMode(BuildMode.release), true);
      expect(device.supportsRuntimeMode(BuildMode.jitRelease), false);
    });

    testWithoutContext('lists nothing when workflow cannot list devices', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux'),
        fuchsiaSdk: null,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.canListDevices).thenReturn(false);

      expect(fuchsiaDevices.canListAnything, false);
      expect(await fuchsiaDevices.pollingGetDevices(), isEmpty);
    });

    testWithoutContext('can parse ffx output for single device', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux', environment: <String, String>{},),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(false);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices(useDeviceFinder: false)).thenAnswer((Invocation invocation) async {
        return '2001:0db8:85a3:0000:0000:8a2e:0370:7334 paper-pulp-bush-angel';
      });

      final Device device = (await fuchsiaDevices.pollingGetDevices()).single;

      expect(device.name, 'paper-pulp-bush-angel');
      expect(device.id, '192.168.42.10');
    });

    testWithoutContext('can parse device-finder output for single device', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux', environment: <String, String>{'FUCHSIA_DISABLED_ffx_discovery': '1'},),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(true);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices(useDeviceFinder: true)).thenAnswer((Invocation invocation) async {
        return '2001:0db8:85a3:0000:0000:8a2e:0370:7334 paper-pulp-bush-angel';
      });

      final Device device = (await fuchsiaDevices.pollingGetDevices()).single;

      expect(device.name, 'paper-pulp-bush-angel');
      expect(device.id, '192.168.11.999');
    });

    testWithoutContext('can parse ffx output for multiple devices', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux'),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(false);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices(useDeviceFinder: false)).thenAnswer((Invocation invocation) async {
        return '2001:0db8:85a3:0000:0000:8a2e:0370:7334 paper-pulp-bush-angel\n'
          '2001:0db8:85a3:0000:0000:8a2e:0370:7335 foo-bar-fiz-buzz';
      });

      final List<Device> devices = await fuchsiaDevices.pollingGetDevices();

      expect(devices.first.name, 'paper-pulp-bush-angel');
      expect(devices.first.id, '192.168.42.10');
      expect(devices.last.name, 'foo-bar-fiz-buzz');
      expect(devices.last.id, '192.168.42.10');
    });

    testWithoutContext('can parse device-finder output for multiple devices', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux'),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(true);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices(useDeviceFinder: true)).thenAnswer((Invocation invocation) async {
        return '2001:0db8:85a3:0000:0000:8a2e:0370:7334 paper-pulp-bush-angel\n'
          '2001:0db8:85a3:0000:0000:8a2e:0370:7335 foo-bar-fiz-buzz';
      });

      final List<Device> devices = await fuchsiaDevices.pollingGetDevices();

      expect(devices.first.name, 'paper-pulp-bush-angel');
      expect(devices.first.id, '192.168.11.999');
      expect(devices.last.name, 'foo-bar-fiz-buzz');
      expect(devices.last.id, '192.168.11.999');
    });

    testWithoutContext('can parse junk output from ffx', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux'),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(false);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices()).thenAnswer((Invocation invocation) async {
        return 'junk';
      });

      final List<Device> devices = await fuchsiaDevices.pollingGetDevices();

      expect(devices, isEmpty);
    });

    testWithoutContext('can parse junk output from device-finder', () async {
      final MockFuchsiaWorkflow fuchsiaWorkflow = MockFuchsiaWorkflow();
      final MockFuchsiaSdk fuchsiaSdk = MockFuchsiaSdk();
      final FuchsiaDevices fuchsiaDevices = FuchsiaDevices(
        platform: FakePlatform(operatingSystem: 'linux'),
        fuchsiaSdk: fuchsiaSdk,
        fuchsiaWorkflow: fuchsiaWorkflow,
        logger: BufferLogger.test(),
      );
      when(fuchsiaWorkflow.shouldUseDeviceFinder).thenReturn(true);
      when(fuchsiaWorkflow.canListDevices).thenReturn(true);
      when(fuchsiaSdk.listDevices(useDeviceFinder: true)).thenAnswer((Invocation invocation) async {
        return 'junk';
      });

      final List<Device> devices = await fuchsiaDevices.pollingGetDevices();

      expect(devices, isEmpty);
    });

    testUsingContext('disposing device disposes the portForwarder', () async {
      final MockPortForwarder mockPortForwarder = MockPortForwarder();
      final FuchsiaDevice device = FuchsiaDevice('123');
      device.portForwarder = mockPortForwarder;
      await device.dispose();
      verify(mockPortForwarder.dispose()).called(1);
    });

    testWithoutContext('default capabilities', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
      memoryFileSystem.directory('fuchsia').createSync(recursive: true);
      memoryFileSystem.file('pubspec.yaml').createSync();

      expect(device.supportsHotReload, true);
      expect(device.supportsHotRestart, false);
      expect(device.supportsFlutterExit, false);
      expect(device.isSupportedForProject(project), true);
    });

    test('is ephemeral', () {
      final FuchsiaDevice device = FuchsiaDevice('123');

      expect(device.ephemeral, true);
    });

    testWithoutContext('supported for project', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
      memoryFileSystem.directory('fuchsia').createSync(recursive: true);
      memoryFileSystem.file('pubspec.yaml').createSync();

      expect(device.isSupportedForProject(project), true);
    });

    testWithoutContext('not supported for project', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
      memoryFileSystem.file('pubspec.yaml').createSync();

      expect(device.isSupportedForProject(project), false);
    });

    testUsingContext('targetPlatform does not throw when sshConfig is missing', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');

      expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: null),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });

    testUsingContext('targetPlatform arm64 works', () async {
      when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
        return ProcessResult(1, 0, 'aarch64', '');
      });
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });

    testUsingContext('targetPlatform x64 works', () async {
      when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
        return ProcessResult(1, 0, 'x86_64', '');
      });
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.targetPlatform, TargetPlatform.fuchsia_x64);
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });

    testUsingContext('hostAddress parsing works', () async {
      when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
        return ProcessResult(
          1,
          0,
          'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
          '',
        );
      });
      final FuchsiaDevice device = FuchsiaDevice('id');
      expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003');
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });

    testUsingContext('hostAddress parsing throws tool error on failure', () async {
      when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
        return ProcessResult(1, 1, '', '');
      });
      final FuchsiaDevice device = FuchsiaDevice('id');
      expect(() async => device.hostAddress, throwsToolExit());
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });

    testUsingContext('hostAddress parsing throws tool error on empty response', () async {
      when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
        return ProcessResult(1, 0, '', '');
      });
      final FuchsiaDevice device = FuchsiaDevice('id');
      expect(() async => device.hostAddress, throwsToolExit());
    }, overrides: <Type, Generator>{
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
      ProcessManager: () => MockProcessManager(),
    });
  });

  group('displays friendly error when', () {
    MockProcessManager mockProcessManager;
    MockProcessResult mockProcessResult;
    File artifactFile;
    MockProcessManager emptyStdoutProcessManager;
    MockProcessResult emptyStdoutProcessResult;

    setUp(() {
      mockProcessManager = MockProcessManager();
      mockProcessResult = MockProcessResult();
      artifactFile = MemoryFileSystem.test().file('artifact');
      when(mockProcessManager.run(
        any,
        environment: anyNamed('environment'),
        workingDirectory: anyNamed('workingDirectory'),
      )).thenAnswer((Invocation invocation) =>
          Future<ProcessResult>.value(mockProcessResult));
      when(mockProcessResult.exitCode).thenReturn(1);
      when<String>(mockProcessResult.stdout as String).thenReturn('');
      when<String>(mockProcessResult.stderr as String).thenReturn('');

      emptyStdoutProcessManager = MockProcessManager();
      emptyStdoutProcessResult = MockProcessResult();
      when(emptyStdoutProcessManager.run(
        any,
        environment: anyNamed('environment'),
        workingDirectory: anyNamed('workingDirectory'),
      )).thenAnswer((Invocation invocation) =>
          Future<ProcessResult>.value(emptyStdoutProcessResult));
      when(emptyStdoutProcessResult.exitCode).thenReturn(0);
      when<String>(emptyStdoutProcessResult.stdout as String).thenReturn('');
      when<String>(emptyStdoutProcessResult.stderr as String).thenReturn('');
    });

    testUsingContext('No vmservices found', () async {
      final FuchsiaDevice device = FuchsiaDevice('id');
      ToolExit toolExit;
      try {
        await device.servicePorts();
      } on ToolExit catch (err) {
        toolExit = err;
      }
      expect(
          toolExit.message,
          contains(
              'No Dart Observatories found. Are you running a debug build?'));
    }, overrides: <Type, Generator>{
      ProcessManager: () => emptyStdoutProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(
            sshConfig: artifactFile,
            devFinder: artifactFile,
            ffx: artifactFile,
          ),
      FuchsiaSdk: () => MockFuchsiaSdk(),
    });

    group('device logs', () {
      const String exampleUtcLogs = '''
[2018-11-09 01:27:45][3][297950920][log] INFO: example_app.cmx(flutter): Error doing thing
[2018-11-09 01:27:58][46257][46269][foo] INFO: Using a thing
[2018-11-09 01:29:58][46257][46269][foo] INFO: Blah blah blah
[2018-11-09 01:29:58][46257][46269][foo] INFO: other_app.cmx(flutter): Do thing
[2018-11-09 01:30:02][41175][41187][bar] INFO: Invoking a bar
[2018-11-09 01:30:12][52580][52983][log] INFO: example_app.cmx(flutter): Did thing this time

  ''';
      MockProcessManager mockProcessManager;
      MockProcess mockProcess;
      Completer<int> exitCode;
      StreamController<List<int>> stdout;
      StreamController<List<int>> stderr;
      File devFinder;
      File ffx;
      File sshConfig;

      setUp(() {
        mockProcessManager = MockProcessManager();
        mockProcess = MockProcess();
        stdout = StreamController<List<int>>(sync: true);
        stderr = StreamController<List<int>>(sync: true);
        exitCode = Completer<int>();
        when(mockProcessManager.start(any))
            .thenAnswer((Invocation _) => Future<Process>.value(mockProcess));
        when(mockProcess.exitCode).thenAnswer((Invocation _) => exitCode.future);
        when(mockProcess.stdout).thenAnswer((Invocation _) => stdout.stream);
        when(mockProcess.stderr).thenAnswer((Invocation _) => stderr.stream);
        final FileSystem memoryFileSystem = MemoryFileSystem.test();
        devFinder = memoryFileSystem.file('device-finder')..writeAsStringSync('\n');
        ffx = memoryFileSystem.file('ffx')..writeAsStringSync('\n');
        sshConfig = memoryFileSystem.file('ssh_config')..writeAsStringSync('\n');
      });

      tearDown(() {
        exitCode.complete(0);
      });

      testUsingContext('can be parsed for an app', () async {
        final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
        final DeviceLogReader reader = device.getLogReader(
            app: FuchsiaModulePackage(name: 'example_app'));
        final List<String> logLines = <String>[];
        final Completer<void> lock = Completer<void>();
        reader.logLines.listen((String line) {
          logLines.add(line);
          if (logLines.length == 2) {
            lock.complete();
          }
        });
        expect(logLines, isEmpty);

        stdout.add(utf8.encode(exampleUtcLogs));
        await stdout.close();
        await lock.future.timeout(const Duration(seconds: 1));

        expect(logLines, <String>[
          '[2018-11-09 01:27:45.000] Flutter: Error doing thing',
          '[2018-11-09 01:30:12.000] Flutter: Did thing this time',
        ]);
      }, overrides: <Type, Generator>{
        ProcessManager: () => mockProcessManager,
        SystemClock: () => SystemClock.fixed(DateTime(2018, 11, 9, 1, 25, 45)),
        FuchsiaArtifacts: () =>
            FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig, ffx: ffx),
      });

      testUsingContext('cuts off prior logs', () async {
        final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
        final DeviceLogReader reader = device.getLogReader(
            app: FuchsiaModulePackage(name: 'example_app'));
        final List<String> logLines = <String>[];
        final Completer<void> lock = Completer<void>();
        reader.logLines.listen((String line) {
          logLines.add(line);
          lock.complete();
        });
        expect(logLines, isEmpty);

        stdout.add(utf8.encode(exampleUtcLogs));
        await stdout.close();
        await lock.future.timeout(const Duration(seconds: 1));

        expect(logLines, <String>[
          '[2018-11-09 01:30:12.000] Flutter: Did thing this time',
        ]);
      }, overrides: <Type, Generator>{
        ProcessManager: () => mockProcessManager,
        SystemClock: () => SystemClock.fixed(DateTime(2018, 11, 9, 1, 29, 45)),
        FuchsiaArtifacts: () =>
            FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig, ffx: ffx),
      });

      testUsingContext('can be parsed for all apps', () async {
        final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
        final DeviceLogReader reader = device.getLogReader();
        final List<String> logLines = <String>[];
        final Completer<void> lock = Completer<void>();
        reader.logLines.listen((String line) {
          logLines.add(line);
          if (logLines.length == 3) {
            lock.complete();
          }
        });
        expect(logLines, isEmpty);

        stdout.add(utf8.encode(exampleUtcLogs));
        await stdout.close();
        await lock.future.timeout(const Duration(seconds: 1));

        expect(logLines, <String>[
          '[2018-11-09 01:27:45.000] Flutter: Error doing thing',
          '[2018-11-09 01:29:58.000] Flutter: Do thing',
          '[2018-11-09 01:30:12.000] Flutter: Did thing this time',
        ]);
      }, overrides: <Type, Generator>{
        ProcessManager: () => mockProcessManager,
        SystemClock: () => SystemClock.fixed(DateTime(2018, 11, 9, 1, 25, 45)),
        FuchsiaArtifacts: () =>
            FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig, ffx: ffx),
      });
    });
  });

  group('screenshot', () {
    testUsingContext('is supported on posix platforms', () {
      final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
      expect(device.supportsScreenshot, true);
    }, overrides: <Type, Generator>{
      Platform: () => FakePlatform(
        operatingSystem: 'linux',
      ),
    });

    testUsingContext('is not supported on Windows', () {
      final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');

      expect(device.supportsScreenshot, false);
    }, overrides: <Type, Generator>{
      Platform: () => FakePlatform(
        operatingSystem: 'windows',
      ),
    });

    test("takeScreenshot throws if file isn't .ppm", () async {
      final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
      await expectLater(
        () => device.takeScreenshot(globals.fs.file('file.invalid')),
        throwsA(equals('file.invalid must be a .ppm file')),
      );
    });

    testUsingContext('takeScreenshot throws if screencap failed', () async {
      final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');

      when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'screencap > /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 1, '', '<error-message>'));

      await expectLater(
        () => device.takeScreenshot(globals.fs.file('file.ppm')),
        throwsA(equals('Could not take a screenshot on device tester:\n<error-message>')),
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => MockProcessManager(),
      FileSystem: () => MemoryFileSystem.test(),
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FUCHSIA_SSH_CONFIG': '/fuchsia/out/default/.ssh',
        },
        operatingSystem: 'linux',
      ),
    });

    testUsingContext('takeScreenshot throws if scp failed', () async {
      final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');

      when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'screencap > /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

      when(globals.processManager.run(
        const <String>[
          'scp',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0:/tmp/screenshot.ppm',
          'file.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 1, '', '<error-message>'));

       when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'rm /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

      await expectLater(
        () => device.takeScreenshot(globals.fs.file('file.ppm')),
        throwsA(equals('Failed to copy screenshot from device:\n<error-message>')),
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => MockProcessManager(),
      FileSystem: () => MemoryFileSystem.test(),
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FUCHSIA_SSH_CONFIG': '/fuchsia/out/default/.ssh',
        },
        operatingSystem: 'linux',
      ),
    });

    testUsingContext("takeScreenshot prints error if can't delete file from device", () async {
      final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');

      when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'screencap > /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

      when(globals.processManager.run(
        const <String>[
          'scp',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0:/tmp/screenshot.ppm',
          'file.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

       when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'rm /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 1, '', '<error-message>'));

      try {
        await device.takeScreenshot(globals.fs.file('file.ppm'));
      } on Exception {
        assert(false);
      }
      expect(
        testLogger.errorText,
        contains('Failed to delete screenshot.ppm from the device:\n<error-message>'),
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => MockProcessManager(),
      FileSystem: () => MemoryFileSystem.test(),
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FUCHSIA_SSH_CONFIG': '/fuchsia/out/default/.ssh',
        },
        operatingSystem: 'linux',
      ),
    }, testOn: 'posix');

    testUsingContext('takeScreenshot returns', () async {
      final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');

      when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'screencap > /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

      when(globals.processManager.run(
        const <String>[
          'scp',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0:/tmp/screenshot.ppm',
          'file.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

       when(globals.processManager.run(
        const <String>[
          'ssh',
          '-F',
          '/fuchsia/out/default/.ssh',
          '0.0.0.0',
          'rm /tmp/screenshot.ppm',
        ],
        workingDirectory: anyNamed('workingDirectory'),
        environment: anyNamed('environment'),
      )).thenAnswer((_) async => ProcessResult(0, 0, '', ''));

      expect(() async => device.takeScreenshot(globals.fs.file('file.ppm')),
        returnsNormally);
    }, overrides: <Type, Generator>{
      ProcessManager: () => MockProcessManager(),
      FileSystem: () => MemoryFileSystem.test(),
      Platform: () => FakePlatform(
        environment: <String, String>{
          'FUCHSIA_SSH_CONFIG': '/fuchsia/out/default/.ssh',
        },
        operatingSystem: 'linux',
      ),
    });
  });

  group('portForwarder', () {
    MockProcessManager mockProcessManager;
    File sshConfig;

    setUp(() {
      mockProcessManager = MockProcessManager();
      sshConfig = MemoryFileSystem.test().file('irrelevant')..writeAsStringSync('\n');
    });

    testUsingContext('`unforward` prints stdout and stderr if ssh command failed', () async {
      final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');

      final MockProcessResult mockFailureProcessResult = MockProcessResult();
      when(mockFailureProcessResult.exitCode).thenReturn(1);
      when<String>(mockFailureProcessResult.stdout as String).thenReturn('<stdout>');
      when<String>(mockFailureProcessResult.stderr as String).thenReturn('<stderr>');
      when(mockProcessManager.run(<String>[
        'ssh',
        '-F',
        sshConfig.absolute.path,
        '-O',
        'cancel',
        '-vvv',
        '-L',
        '0:127.0.0.1:1',
        'id',
      ])).thenAnswer((Invocation invocation) {
        return Future<ProcessResult>.value(mockFailureProcessResult);
      });
      await expectLater(
        () => device.portForwarder.unforward(ForwardedPort(/*hostPort=*/ 0, /*devicePort=*/ 1)),
        throwsToolExit(message: 'Unforward command failed:\nstdout: <stdout>\nstderr: <stderr>'),
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => mockProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
    });
  });


  group('FuchsiaIsolateDiscoveryProtocol', () {
    MockPortForwarder portForwarder;

    setUp(() {
      portForwarder = MockPortForwarder();
    });

    Future<Uri> findUri(List<FlutterView> views, String expectedIsolateName) async {
      final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
        requests: <VmServiceExpectation>[
          FakeVmServiceRequest(
            method: kListViewsMethod,
            jsonResponse: <String, Object>{
              'views': <Object>[
                for (FlutterView view in views)
                  view.toJson()
              ],
            },
          ),
        ],
        httpAddress: Uri.parse('example'),
      );
      final MockFuchsiaDevice fuchsiaDevice =
        MockFuchsiaDevice('123', portForwarder, false);
      final FuchsiaIsolateDiscoveryProtocol discoveryProtocol =
        FuchsiaIsolateDiscoveryProtocol(
        fuchsiaDevice,
        expectedIsolateName,
        (Uri uri) async => fakeVmServiceHost.vmService,
        (Device device, Uri uri, bool enableServiceAuthCodes) => null,
        true, // only poll once.
      );
      final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
      when(fuchsiaDevice.dds).thenReturn(mockDds);
      when(mockDds.startDartDevelopmentService(any, any, any, any)).thenReturn(null);
      when(mockDds.uri).thenReturn(Uri.parse('example'));
      when(fuchsiaDevice.servicePorts())
          .thenAnswer((Invocation invocation) async => <int>[1]);
      when(portForwarder.forward(1))
          .thenAnswer((Invocation invocation) async => 2);
      return await discoveryProtocol.uri;
    }

    testUsingContext('can find flutter view with matching isolate name', () async {
      const String expectedIsolateName = 'foobar';
      final Uri uri = await findUri(<FlutterView>[
        // no ui isolate.
        FlutterView(id: '1', uiIsolate: null),
        // wrong name.
        FlutterView(
          id: '2',
          uiIsolate: vm_service.Isolate.parse(<String, dynamic>{
            ...fakeIsolate.toJson(),
            'name': 'Wrong name',
          }),
        ),
        // matching name.
        FlutterView(
          id: '3',
          uiIsolate: vm_service.Isolate.parse(<String, dynamic>{
             ...fakeIsolate.toJson(),
            'name': expectedIsolateName,
          }),
        ),
      ], expectedIsolateName);

      expect(
          uri.toString(), 'http://${InternetAddress.loopbackIPv4.address}:0/');
    });

    testUsingContext('can handle flutter view without matching isolate name', () async {
      const String expectedIsolateName = 'foobar';
      final Future<Uri> uri = findUri(<FlutterView>[
        // no ui isolate.
        FlutterView(id: '1', uiIsolate: null),
        // wrong name.
        FlutterView(id: '2', uiIsolate: vm_service.Isolate.parse(<String, Object>{
           ...fakeIsolate.toJson(),
          'name': 'wrong name',
        })),
      ], expectedIsolateName);

      expect(uri, throwsException);
    });

    testUsingContext('can handle non flutter view', () async {
      const String expectedIsolateName = 'foobar';
      final Future<Uri> uri = findUri(<FlutterView>[
        FlutterView(id: '1', uiIsolate: null), // no ui isolate.
      ], expectedIsolateName);

      expect(uri, throwsException);
    });
  });

  testUsingContext('Correct flutter runner', () async {
    final Cache cache = Cache.test(
      processManager: FakeProcessManager.any(),
    );
    final FileSystem fileSystem = MemoryFileSystem.test();
    final CachedArtifacts artifacts = CachedArtifacts(
      cache: cache,
      fileSystem: fileSystem,
      platform: FakePlatform(operatingSystem: 'linux'),
      operatingSystemUtils: globals.os,
    );
    expect(artifacts.getArtifactPath(
        Artifact.fuchsiaFlutterRunner,
        platform: TargetPlatform.fuchsia_x64,
        mode: BuildMode.debug,
      ),
      contains('flutter_jit_runner'),
    );
    expect(artifacts.getArtifactPath(
        Artifact.fuchsiaFlutterRunner,
        platform: TargetPlatform.fuchsia_x64,
        mode: BuildMode.profile,
      ),
      contains('flutter_aot_runner'),
    );
    expect(artifacts.getArtifactPath(
        Artifact.fuchsiaFlutterRunner,
        platform: TargetPlatform.fuchsia_x64,
        mode: BuildMode.release,
      ),
      contains('flutter_aot_product_runner'),
    );
    expect(artifacts.getArtifactPath(
        Artifact.fuchsiaFlutterRunner,
        platform: TargetPlatform.fuchsia_x64,
        mode: BuildMode.jitRelease,
      ),
      contains('flutter_jit_product_runner'),
    );
  });

  group('Fuchsia app start and stop: ', () {
    MemoryFileSystem memoryFileSystem;
    FakeOperatingSystemUtils osUtils;
    FakeFuchsiaDeviceTools fuchsiaDeviceTools;
    MockFuchsiaSdk fuchsiaSdk;
    Artifacts artifacts;
    FakeProcessManager fakeSuccessfulProcessManager;
    FakeProcessManager fakeFailedProcessManager;
    File sshConfig;

    setUp(() {
      memoryFileSystem = MemoryFileSystem.test();
      osUtils = FakeOperatingSystemUtils();
      fuchsiaDeviceTools = FakeFuchsiaDeviceTools();
      fuchsiaSdk = MockFuchsiaSdk();
      sshConfig = MemoryFileSystem.test().file('ssh_config')..writeAsStringSync('\n');
      artifacts = Artifacts.test();
      for (final BuildMode mode in <BuildMode>[BuildMode.debug, BuildMode.release]) {
        memoryFileSystem.file(
          artifacts.getArtifactPath(Artifact.fuchsiaKernelCompiler,
              platform: TargetPlatform.fuchsia_arm64, mode: mode),
        ).createSync();

        memoryFileSystem.file(
          artifacts.getArtifactPath(Artifact.platformKernelDill,
              platform: TargetPlatform.fuchsia_arm64, mode: mode),
        ).createSync();

        memoryFileSystem.file(
          artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath,
              platform: TargetPlatform.fuchsia_arm64, mode: mode),
        ).createSync();

        memoryFileSystem.file(
          artifacts.getArtifactPath(Artifact.fuchsiaFlutterRunner,
              platform: TargetPlatform.fuchsia_arm64, mode: mode),
        ).createSync();
      }
      fakeSuccessfulProcessManager = FakeProcessManager.list(<FakeCommand>[
        FakeCommand(
          command: <String>['ssh', '-F', sshConfig.absolute.path, '123', r'echo $SSH_CONNECTION'],
          stdout: 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
        ),
      ]);
      fakeFailedProcessManager = FakeProcessManager.list(<FakeCommand>[
        FakeCommand(
          command: <String>['ssh', '-F', sshConfig.absolute.path, '123', r'echo $SSH_CONNECTION'],
          stdout: '',
          stderr: '',
          exitCode: 1,
        ),
      ]);
    });

    Future<LaunchResult> setupAndStartApp({
      @required bool prebuilt,
      @required BuildMode mode,
    }) async {
      const String appName = 'app_name';
      final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
      globals.fs.directory('fuchsia').createSync(recursive: true);
      final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
      pubspecFile.writeAsStringSync('name: $appName');

      FuchsiaApp app;
      if (prebuilt) {
        final File far = globals.fs.file('app_name-0.far')..createSync();
        app = FuchsiaApp.fromPrebuiltApp(far);
      } else {
        globals.fs.file(globals.fs.path.join('fuchsia', 'meta', '$appName.cmx'))
          ..createSync(recursive: true)
          ..writeAsStringSync('{}');
        globals.fs.file('.packages').createSync();
        globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
        app = BuildableFuchsiaApp(project: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory).fuchsia);
      }

      final DebuggingOptions debuggingOptions = DebuggingOptions.disabled(BuildInfo(mode, null, treeShakeIcons: false));
      return device.startApp(
        app,
        prebuiltApplication: prebuilt,
        debuggingOptions: debuggingOptions,
      );
    }

    testUsingContext('start prebuilt in release mode', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
      expect(launchResult.started, isTrue);
      expect(launchResult.hasObservatory, isFalse);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('start and stop prebuilt in release mode', () async {
      const String appName = 'app_name';
      final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
      globals.fs.directory('fuchsia').createSync(recursive: true);
      final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
      pubspecFile.writeAsStringSync('name: $appName');
      final File far = globals.fs.file('app_name-0.far')..createSync();

      final FuchsiaApp app = FuchsiaApp.fromPrebuiltApp(far);
      final DebuggingOptions debuggingOptions =
          DebuggingOptions.disabled(const BuildInfo(BuildMode.release, null, treeShakeIcons: false));
      final LaunchResult launchResult = await device.startApp(app,
          prebuiltApplication: true,
          debuggingOptions: debuggingOptions);
      expect(launchResult.started, isTrue);
      expect(launchResult.hasObservatory, isFalse);
      expect(await device.stopApp(app), isTrue);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('start prebuilt in debug mode', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: true, mode: BuildMode.debug);
      expect(launchResult.started, isTrue);
      expect(launchResult.hasObservatory, isTrue);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('start buildable in release mode', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: false, mode: BuildMode.release);
      expect(launchResult.started, isTrue);
      expect(launchResult.hasObservatory, isFalse);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.list(<FakeCommand>[
            const FakeCommand(
              command: <String>[
                'Artifact.genSnapshot.TargetPlatform.fuchsia_arm64.release',
                '--deterministic',
                '--snapshot_kind=app-aot-elf',
                '--elf=build/fuchsia/elf.aotsnapshot',
                'build/fuchsia/app_name.dil'
              ],
            ),
            FakeCommand(
              command: <String>['ssh', '-F', sshConfig.absolute.path, '123', r'echo $SSH_CONNECTION'],
              stdout: 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
            ),
          ]),
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('start buildable in debug mode', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: false, mode: BuildMode.debug);
      expect(launchResult.started, isTrue);
      expect(launchResult.hasObservatory, isTrue);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('fail when cant get ssh config', () async {
      expect(() async =>
          setupAndStartApp(prebuilt: true, mode: BuildMode.release),
          throwsToolExit(message: 'Cannot interact with device. No ssh config.\n'
                                  'Try setting FUCHSIA_SSH_CONFIG or FUCHSIA_BUILD_DIR.'));
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: null),
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('fail when cant get host address', () async {
      expect(() async =>
        setupAndStartApp(prebuilt: true, mode: BuildMode.release),
          throwsToolExit(message: 'Failed to get local address, aborting.'));
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeFailedProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('fail with correct LaunchResult when pm fails', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
      expect(launchResult.started, isFalse);
      expect(launchResult.hasObservatory, isFalse);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => fuchsiaDeviceTools,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(pm: FailingPM()),
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('fail with correct LaunchResult when amber fails', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
      expect(launchResult.started, isFalse);
      expect(launchResult.hasObservatory, isFalse);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(amber: FailingAmberCtl()),
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

    testUsingContext('fail with correct LaunchResult when tiles fails', () async {
      final LaunchResult launchResult =
          await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
      expect(launchResult.started, isFalse);
      expect(launchResult.hasObservatory, isFalse);
    }, overrides: <Type, Generator>{
      Artifacts: () => artifacts,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeSuccessfulProcessManager,
      FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(tiles: FailingTilesCtl()),
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => fuchsiaSdk,
      OperatingSystemUtils: () => osUtils,
    });

  });

  group('sdkNameAndVersion: ', () {
    File sshConfig;
    MockProcessManager mockSuccessProcessManager;
    MockProcessResult mockSuccessProcessResult;
    MockProcessManager mockFailureProcessManager;
    MockProcessResult mockFailureProcessResult;
    MockProcessManager emptyStdoutProcessManager;
    MockProcessResult emptyStdoutProcessResult;

    setUp(() {
      sshConfig = MemoryFileSystem.test().file('ssh_config')..writeAsStringSync('\n');

      mockSuccessProcessManager = MockProcessManager();
      mockSuccessProcessResult = MockProcessResult();
      when(mockSuccessProcessManager.run(any)).thenAnswer(
          (Invocation invocation) => Future<ProcessResult>.value(mockSuccessProcessResult));
      when(mockSuccessProcessResult.exitCode).thenReturn(0);
      when<String>(mockSuccessProcessResult.stdout as String).thenReturn('version');
      when<String>(mockSuccessProcessResult.stderr as String).thenReturn('');

      mockFailureProcessManager = MockProcessManager();
      mockFailureProcessResult = MockProcessResult();
      when(mockFailureProcessManager.run(any)).thenAnswer(
          (Invocation invocation) => Future<ProcessResult>.value(mockFailureProcessResult));
      when(mockFailureProcessResult.exitCode).thenReturn(1);
      when<String>(mockFailureProcessResult.stdout as String).thenReturn('');
      when<String>(mockFailureProcessResult.stderr as String).thenReturn('');

      emptyStdoutProcessManager = MockProcessManager();
      emptyStdoutProcessResult = MockProcessResult();
      when(emptyStdoutProcessManager.run(any)).thenAnswer((Invocation invocation) =>
          Future<ProcessResult>.value(emptyStdoutProcessResult));
      when(emptyStdoutProcessResult.exitCode).thenReturn(0);
      when<String>(emptyStdoutProcessResult.stdout as String).thenReturn('');
      when<String>(emptyStdoutProcessResult.stderr as String).thenReturn('');
    });

    testUsingContext('does not throw on non-existant ssh config', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.sdkNameAndVersion, equals('Fuchsia'));
    }, overrides: <Type, Generator>{
      ProcessManager: () => mockSuccessProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: null),
      FuchsiaSdk: () => MockFuchsiaSdk(),
    });

    testUsingContext('returns what we get from the device on success', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.sdkNameAndVersion, equals('Fuchsia version'));
    }, overrides: <Type, Generator>{
      ProcessManager: () => mockSuccessProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
    });

    testUsingContext('returns "Fuchsia" when device command fails', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.sdkNameAndVersion, equals('Fuchsia'));
    }, overrides: <Type, Generator>{
      ProcessManager: () => mockFailureProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
    });

    testUsingContext('returns "Fuchsia" when device gives an empty result', () async {
      final FuchsiaDevice device = FuchsiaDevice('123');
      expect(await device.sdkNameAndVersion, equals('Fuchsia'));
    }, overrides: <Type, Generator>{
      ProcessManager: () => emptyStdoutProcessManager,
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
      FuchsiaSdk: () => MockFuchsiaSdk(),
    });
  });
}

class FuchsiaModulePackage extends ApplicationPackage {
  FuchsiaModulePackage({@required this.name}) : super(id: name);

  @override
  final String name;
}

class MockProcessManager extends Mock implements ProcessManager {}

class MockProcessResult extends Mock implements ProcessResult {}

class MockProcess extends Mock implements Process {}

Process _createMockProcess({
  int exitCode = 0,
  String stdout = '',
  String stderr = '',
  bool persistent = false,
}) {
  final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[
    utf8.encode(stdout),
  ]);
  final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(<List<int>>[
    utf8.encode(stderr),
  ]);
  final Process process = MockProcess();

  when(process.stdout).thenAnswer((_) => stdoutStream);
  when(process.stderr).thenAnswer((_) => stderrStream);

  if (persistent) {
    final Completer<int> exitCodeCompleter = Completer<int>();
    when(process.kill()).thenAnswer((_) {
      exitCodeCompleter.complete(-11);
      return true;
    });
    when(process.exitCode).thenAnswer((_) => exitCodeCompleter.future);
  } else {
    when(process.exitCode).thenAnswer((_) => Future<int>.value(exitCode));
  }
  return process;
}

class MockFuchsiaDevice extends Mock implements FuchsiaDevice {
  MockFuchsiaDevice(this.id, this.portForwarder, this._ipv6);

  final bool _ipv6;

  @override
  bool get ipv6 => _ipv6;

  @override
  final String id;

  @override
  final DevicePortForwarder portForwarder;

  @override
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.fuchsia_arm64;
}

class MockPortForwarder extends Mock implements DevicePortForwarder {}

class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice {
  FuchsiaDeviceWithFakeDiscovery(String id, {String name}) : super(id, name: name);

  @override
  FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol(String isolateName) {
    return FakeFuchsiaIsolateDiscoveryProtocol();
  }

  @override
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.fuchsia_arm64;
}

class FakeFuchsiaIsolateDiscoveryProtocol implements FuchsiaIsolateDiscoveryProtocol {
  @override
  FutureOr<Uri> get uri => Uri.parse('http://[::1]:37');

  @override
  void dispose() {}
}

class FakeFuchsiaAmberCtl implements FuchsiaAmberCtl {
  @override
  Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return true;
  }

  @override
  Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return true;
  }

  @override
  Future<bool> getUp(FuchsiaDevice device, String packageName) async {
    return true;
  }

  @override
  Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return true;
  }

  @override
  Future<bool> pkgCtlResolve(FuchsiaDevice device, FuchsiaPackageServer server, String packageName) async {
    return true;
  }

  @override
  Future<bool> pkgCtlRepoRemove(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return true;
  }
}

class FailingAmberCtl implements FuchsiaAmberCtl {
  @override
  Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return false;
  }

  @override
  Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return false;
  }

  @override
  Future<bool> getUp(FuchsiaDevice device, String packageName) async {
    return false;
  }

  @override
  Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return false;
  }

  @override
  Future<bool> pkgCtlResolve(FuchsiaDevice device, FuchsiaPackageServer server, String packageName) async {
    return false;
  }

  @override
  Future<bool> pkgCtlRepoRemove(FuchsiaDevice device, FuchsiaPackageServer server) async {
    return false;
  }
}

class FakeFuchsiaTilesCtl implements FuchsiaTilesCtl {
  final Map<int, String> _runningApps = <int, String>{};
  bool _started = false;
  int _nextAppId = 1;

  @override
  Future<bool> start(FuchsiaDevice device) async {
    _started = true;
    return true;
  }

  @override
  Future<Map<int, String>> list(FuchsiaDevice device) async {
    if (!_started) {
      return null;
    }
    return _runningApps;
  }

  @override
  Future<bool> add(FuchsiaDevice device, String url, List<String> args) async {
    if (!_started) {
      return false;
    }
    _runningApps[_nextAppId] = url;
    _nextAppId++;
    return true;
  }

  @override
  Future<bool> remove(FuchsiaDevice device, int key) async {
    if (!_started) {
      return false;
    }
    _runningApps.remove(key);
    return true;
  }

  @override
  Future<bool> quit(FuchsiaDevice device) async {
    if (!_started) {
      return false;
    }
    _started = false;
    return true;
  }
}

class FailingTilesCtl implements FuchsiaTilesCtl {
  @override
  Future<bool> start(FuchsiaDevice device) async {
    return false;
  }

  @override
  Future<Map<int, String>> list(FuchsiaDevice device) async {
    return null;
  }

  @override
  Future<bool> add(FuchsiaDevice device, String url, List<String> args) async {
    return false;
  }

  @override
  Future<bool> remove(FuchsiaDevice device, int key) async {
    return false;
  }

  @override
  Future<bool> quit(FuchsiaDevice device) async {
    return false;
  }
}

class FakeFuchsiaDeviceTools implements FuchsiaDeviceTools {
  FakeFuchsiaDeviceTools({
    FuchsiaAmberCtl amber,
    FuchsiaTilesCtl tiles,
  }) : amberCtl = amber ?? FakeFuchsiaAmberCtl(),
       tilesCtl = tiles ?? FakeFuchsiaTilesCtl();

  @override
  final FuchsiaAmberCtl amberCtl;

  @override
  final FuchsiaTilesCtl tilesCtl;
}

class FakeFuchsiaPM implements FuchsiaPM {
  String _appName;

  @override
  Future<bool> init(String buildPath, String appName) async {
    if (!globals.fs.directory(buildPath).existsSync()) {
      return false;
    }
    globals.fs
        .file(globals.fs.path.join(buildPath, 'meta', 'package'))
        .createSync(recursive: true);
    _appName = appName;
    return true;
  }

  @override
  Future<bool> genkey(String buildPath, String outKeyPath) async {
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync()) {
      return false;
    }
    globals.fs.file(outKeyPath).createSync(recursive: true);
    return true;
  }

  @override
  Future<bool> build(String buildPath, String keyPath, String manifestPath) async {
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !globals.fs.file(keyPath).existsSync() ||
        !globals.fs.file(manifestPath).existsSync()) {
      return false;
    }
    globals.fs.file(globals.fs.path.join(buildPath, 'meta.far')).createSync(recursive: true);
    return true;
  }

  @override
  Future<bool> archive(String buildPath, String keyPath, String manifestPath) async {
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !globals.fs.file(keyPath).existsSync() ||
        !globals.fs.file(manifestPath).existsSync()) {
      return false;
    }
    if (_appName == null) {
      return false;
    }
    globals.fs
        .file(globals.fs.path.join(buildPath, '$_appName-0.far'))
        .createSync(recursive: true);
    return true;
  }

  @override
  Future<bool> newrepo(String repoPath) async {
    if (!globals.fs.directory(repoPath).existsSync()) {
      return false;
    }
    return true;
  }

  @override
  Future<Process> serve(String repoPath, String host, int port) async {
    return _createMockProcess(persistent: true);
  }

  @override
  Future<bool> publish(String repoPath, String packagePath) async {
    if (!globals.fs.directory(repoPath).existsSync()) {
      return false;
    }
    if (!globals.fs.file(packagePath).existsSync()) {
      return false;
    }
    return true;
  }
}

class FailingPM implements FuchsiaPM {
  @override
  Future<bool> init(String buildPath, String appName) async {
    return false;
  }

  @override
  Future<bool> genkey(String buildPath, String outKeyPath) async {
    return false;
  }

  @override
  Future<bool> build(String buildPath, String keyPath, String manifestPath) async {
    return false;
  }

  @override
  Future<bool> archive(String buildPath, String keyPath, String manifestPath) async {
    return false;
  }

  @override
  Future<bool> newrepo(String repoPath) async {
    return false;
  }

  @override
  Future<Process> serve(String repoPath, String host, int port) async {
    return _createMockProcess(exitCode: 6);
  }

  @override
  Future<bool> publish(String repoPath, String packagePath) async {
    return false;
  }
}

class FakeFuchsiaKernelCompiler implements FuchsiaKernelCompiler {
  @override
  Future<void> build({
    @required FuchsiaProject fuchsiaProject,
    @required String target, // E.g., lib/main.dart
    BuildInfo buildInfo = BuildInfo.debug,
  }) async {
    final String outDir = getFuchsiaBuildDirectory();
    final String appName = fuchsiaProject.project.manifest.appName;
    final String manifestPath = globals.fs.path.join(outDir, '$appName.dilpmanifest');
    globals.fs.file(manifestPath).createSync(recursive: true);
  }
}

class FailingKernelCompiler implements FuchsiaKernelCompiler {
  @override
  Future<void> build({
    @required FuchsiaProject fuchsiaProject,
    @required String target, // E.g., lib/main.dart
    BuildInfo buildInfo = BuildInfo.debug,
  }) async {
    throwToolExit('Build process failed');
  }
}

class FakeFuchsiaDevFinder implements FuchsiaDevFinder {
  @override
  Future<List<String>> list({ Duration timeout }) async {
    return <String>['192.168.11.999 scare-cable-device-finder'];
  }

  @override
  Future<String> resolve(String deviceName) async {
    return '192.168.11.999';
  }
}

class FakeFuchsiaFfx implements FuchsiaFfx {
  @override
  Future<List<String>> list({Duration timeout}) async {
    return <String>['192.168.42.172 scare-cable-skip-ffx'];
  }

  @override
  Future<String> resolve(String deviceName) async {
    return '192.168.42.10';
  }
}

class MockFuchsiaSdk extends Mock implements FuchsiaSdk {
  MockFuchsiaSdk({
    FuchsiaPM pm,
    FuchsiaKernelCompiler compiler,
    FuchsiaDevFinder devFinder,
    FuchsiaFfx ffx,
  }) : fuchsiaPM = pm ?? FakeFuchsiaPM(),
       fuchsiaKernelCompiler = compiler ?? FakeFuchsiaKernelCompiler(),
       fuchsiaDevFinder = devFinder ?? FakeFuchsiaDevFinder(),
       fuchsiaFfx = ffx ?? FakeFuchsiaFfx();

  @override
  final FuchsiaPM fuchsiaPM;

  @override
  final FuchsiaKernelCompiler fuchsiaKernelCompiler;

  @override
  final FuchsiaDevFinder fuchsiaDevFinder;

  @override
  final FuchsiaFfx fuchsiaFfx;
}

class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
class MockFuchsiaWorkflow extends Mock implements FuchsiaWorkflow {}
