// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:typed_data';

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.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/terminal.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/custom_devices.dart';
import 'package:flutter_tools/src/custom_devices/custom_device_config.dart';
import 'package:flutter_tools/src/custom_devices/custom_devices_config.dart';
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';

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

const String linuxFlutterRoot = '/flutter';
const String windowsFlutterRoot = r'C:\flutter';

const String defaultConfigLinux1 = r'''
{
  "$schema": "file:///flutter/packages/flutter_tools/static/custom-devices.schema.json",
  "custom-devices": [
    {
      "id": "pi",
      "label": "Raspberry Pi",
      "sdkNameAndVersion": "Raspberry Pi 4 Model B+",
      "platform": "linux-arm64",
      "enabled": false,
      "ping": [
        "ping",
        "-w",
        "1",
        "-c",
        "1",
        "raspberrypi"
      ],
      "pingSuccessRegex": null,
      "postBuild": null,
      "install": [
        "scp",
        "-r",
        "-o",
        "BatchMode=yes",
        "${localPath}",
        "pi@raspberrypi:/tmp/${appName}"
      ],
      "uninstall": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "rm -rf \"/tmp/${appName}\""
      ],
      "runDebug": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "flutter-pi \"/tmp/${appName}\""
      ],
      "forwardPort": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "-o",
        "ExitOnForwardFailure=yes",
        "-L",
        "127.0.0.1:${hostPort}:127.0.0.1:${devicePort}",
        "pi@raspberrypi",
        "echo 'Port forwarding success'; read"
      ],
      "forwardPortSuccessRegex": "Port forwarding success",
      "screenshot": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "fbgrab /tmp/screenshot.png && cat /tmp/screenshot.png | base64 | tr -d ' \\n\\t'"
      ]
    }
  ]
}
''';
const String defaultConfigLinux2 = r'''
{
  "custom-devices": [
    {
      "id": "pi",
      "label": "Raspberry Pi",
      "sdkNameAndVersion": "Raspberry Pi 4 Model B+",
      "platform": "linux-arm64",
      "enabled": false,
      "ping": [
        "ping",
        "-w",
        "1",
        "-c",
        "1",
        "raspberrypi"
      ],
      "pingSuccessRegex": null,
      "postBuild": null,
      "install": [
        "scp",
        "-r",
        "-o",
        "BatchMode=yes",
        "${localPath}",
        "pi@raspberrypi:/tmp/${appName}"
      ],
      "uninstall": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "rm -rf \"/tmp/${appName}\""
      ],
      "runDebug": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "flutter-pi \"/tmp/${appName}\""
      ],
      "forwardPort": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "-o",
        "ExitOnForwardFailure=yes",
        "-L",
        "127.0.0.1:${hostPort}:127.0.0.1:${devicePort}",
        "pi@raspberrypi",
        "echo 'Port forwarding success'; read"
      ],
      "forwardPortSuccessRegex": "Port forwarding success",
      "screenshot": [
        "ssh",
        "-o",
        "BatchMode=yes",
        "pi@raspberrypi",
        "fbgrab /tmp/screenshot.png && cat /tmp/screenshot.png | base64 | tr -d ' \\n\\t'"
      ]
    }
  ],
  "$schema": "file:///flutter/packages/flutter_tools/static/custom-devices.schema.json"
}
''';

final Platform windowsPlatform = FakePlatform(
  operatingSystem: 'windows',
  environment: <String, String>{
    'FLUTTER_ROOT': windowsFlutterRoot,
  }
);

class FakeTerminal implements Terminal {
  factory FakeTerminal({required Platform platform}) {
    return FakeTerminal._private(
        stdio: FakeStdio(),
        platform: platform
    );
  }

  FakeTerminal._private({
    required this.stdio,
    required Platform platform
  }) :
    terminal = AnsiTerminal(
      stdio: stdio,
      platform: platform
    );

  final FakeStdio stdio;
  final AnsiTerminal terminal;

  void simulateStdin(String line) {
    stdio.simulateStdin(line);
  }

  @override
  set usesTerminalUi(bool value) => terminal.usesTerminalUi = value;

  @override
  bool get usesTerminalUi => terminal.usesTerminalUi;

  @override
  String bolden(String message) => terminal.bolden(message);

  @override
  String clearScreen() => terminal.clearScreen();

  @override
  String color(String message, TerminalColor color) => terminal.color(message, color);

  @override
  Stream<String> get keystrokes => terminal.keystrokes;

  @override
  Future<String> promptForCharInput(
    List<String> acceptedCharacters, {
    required Logger logger,
    String? prompt,
    int? defaultChoiceIndex,
    bool displayAcceptedCharacters = true
  }) => terminal.promptForCharInput(
      acceptedCharacters,
      logger: logger,
      prompt: prompt,
      defaultChoiceIndex: defaultChoiceIndex,
      displayAcceptedCharacters: displayAcceptedCharacters
    );

  @override
  bool get singleCharMode => terminal.singleCharMode;
  @override
  set singleCharMode(bool value) => terminal.singleCharMode = value;

  @override
  bool get stdinHasTerminal => terminal.stdinHasTerminal;

  @override
  String get successMark => terminal.successMark;

  @override
  bool get supportsColor => terminal.supportsColor;

  @override
  bool get supportsEmoji => terminal.supportsEmoji;

  @override
  String get warningMark => terminal.warningMark;

  @override
  int get preferredStyle => terminal.preferredStyle;
}

class FakeCommandRunner extends FlutterCommandRunner {
  FakeCommandRunner({
    required Platform platform,
    required FileSystem fileSystem,
    required Logger logger,
    UserMessages? userMessages
  }) : _platform = platform,
       _fileSystem = fileSystem,
       _logger = logger,
       _userMessages = userMessages ?? UserMessages(),
       assert(platform != null),
       assert(fileSystem != null),
       assert(logger != null);

  final Platform _platform;
  final FileSystem _fileSystem;
  final Logger _logger;
  final UserMessages _userMessages;

  @override
  Future<void> runCommand(ArgResults topLevelResults) async {
    final Logger logger = (topLevelResults['verbose'] as bool) ? VerboseLogger(_logger) : _logger;

    return context.run<void>(
      overrides: <Type, Generator>{
        Logger: () => logger,
      },
      body: () {
        Cache.flutterRoot ??= Cache.defaultFlutterRoot(
          platform: _platform,
          fileSystem: _fileSystem,
          userMessages: _userMessages,
        );
        // For compatibility with tests that set this to a relative path.
        Cache.flutterRoot = _fileSystem.path.normalize(_fileSystem.path.absolute(Cache.flutterRoot!));
        return super.runCommand(topLevelResults);
      }
    );
  }
}

/// May take platform, logger, processManager and fileSystem from context if
/// not explicitly specified.
CustomDevicesCommand createCustomDevicesCommand({
  CustomDevicesConfig Function(FileSystem, Logger)? config,
  Terminal Function(Platform)? terminal,
  Platform? platform,
  FileSystem? fileSystem,
  ProcessManager? processManager,
  Logger? logger,
  PrintFn? usagePrintFn,
  bool featureEnabled = false
}) {
  platform ??= FakePlatform();
  processManager ??= FakeProcessManager.any();
  fileSystem ??= MemoryFileSystem.test();
  usagePrintFn ??= print;
  logger ??= BufferLogger.test();

  return CustomDevicesCommand.test(
    customDevicesConfig: config != null
      ? config(fileSystem, logger)
      : CustomDevicesConfig.test(
        platform: platform,
        fileSystem: fileSystem,
        directory: fileSystem.directory('/'),
        logger: logger
      ),
    operatingSystemUtils: FakeOperatingSystemUtils(
      hostPlatform: platform.isLinux ? HostPlatform.linux_x64
        : platform.isWindows ? HostPlatform.windows_x64
        : platform.isMacOS ? HostPlatform.darwin_x64
        : throw UnsupportedError('Unsupported operating system')
    ),
    terminal: terminal != null
      ? terminal(platform)
      : FakeTerminal(platform: platform),
    platform: platform,
    featureFlags: TestFeatureFlags(areCustomDevicesEnabled: featureEnabled),
    processManager: processManager,
    fileSystem: fileSystem,
    logger: logger,
    usagePrintFn: usagePrintFn,
  );
}

/// May take platform, logger, processManager and fileSystem from context if
/// not explicitly specified.
CommandRunner<void> createCustomDevicesCommandRunner({
  CustomDevicesConfig Function(FileSystem, Logger)? config,
  Terminal Function(Platform)? terminal,
  Platform? platform,
  FileSystem? fileSystem,
  ProcessManager? processManager,
  Logger? logger,
  PrintFn? usagePrintFn,
  bool featureEnabled = false,
}) {
  platform ??= FakePlatform();
  fileSystem ??= MemoryFileSystem.test();
  logger ??= BufferLogger.test();

  return FakeCommandRunner(
    platform: platform,
    fileSystem: fileSystem,
    logger: logger
  )..addCommand(
    createCustomDevicesCommand(
      config: config,
      terminal: terminal,
      platform: platform,
      fileSystem: fileSystem,
      processManager: processManager,
      logger: logger,
      usagePrintFn: usagePrintFn,
      featureEnabled: featureEnabled
    )
  );
}

FakeTerminal createFakeTerminalForAddingSshDevice({
  required Platform platform,
  required String id,
  required String label,
  required String sdkNameAndVersion,
  required String enabled,
  required String hostname,
  required String username,
  required String runDebug,
  required String usePortForwarding,
  required String screenshot,
  required String apply
}) {
  return FakeTerminal(platform: platform)
    ..simulateStdin(id)
    ..simulateStdin(label)
    ..simulateStdin(sdkNameAndVersion)
    ..simulateStdin(enabled)
    ..simulateStdin(hostname)
    ..simulateStdin(username)
    ..simulateStdin(runDebug)
    ..simulateStdin(usePortForwarding)
    ..simulateStdin(screenshot)
    ..simulateStdin(apply);
}

void main() {
  const String featureNotEnabledMessage = 'Custom devices feature must be enabled. Enable using `flutter config --enable-custom-devices`.';

  setUpAll(() {
    Cache.disableLocking();
  });

  group('linux', () {
    setUp(() {
      Cache.flutterRoot = linuxFlutterRoot;
    });

    testUsingContext(
      'custom-devices command shows config file in help when feature is enabled',
      () async {
        final BufferLogger logger = BufferLogger.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          usagePrintFn: (Object o) => logger.printStatus(o.toString()),
          featureEnabled: true
        );
        await expectLater(
          runner.run(const <String>['custom-devices', '--help']),
          completes
        );
        expect(
          logger.statusText,
          contains('Makes changes to the config file at "/.flutter_custom_devices.json".')
        );
      }
    );

    testUsingContext(
      'running custom-devices command without arguments prints usage',
      () async {
        final BufferLogger logger = BufferLogger.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          usagePrintFn: (Object o) => logger.printStatus(o.toString()),
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices']),
          completes
        );
        expect(
          logger.statusText,
          contains('Makes changes to the config file at "/.flutter_custom_devices.json".')
        );
      }
    );

    // test behaviour with disabled feature
    testUsingContext(
      'custom-devices add command fails when feature is not enabled',
      () async {
        final CommandRunner<void> runner = createCustomDevicesCommandRunner();
        expect(
          runner.run(const <String>['custom-devices', 'add']),
          throwsToolExit(message: featureNotEnabledMessage),
        );
      }
    );

    testUsingContext(
      'custom-devices delete command fails when feature is not enabled',
      () async {
        final CommandRunner<void> runner = createCustomDevicesCommandRunner();
        expect(
          runner.run(const <String>['custom-devices', 'delete', '-d', 'testid']),
          throwsToolExit(message: featureNotEnabledMessage),
        );
      }
    );

    testUsingContext(
      'custom-devices list command fails when feature is not enabled',
      () async {
        final CommandRunner<void> runner = createCustomDevicesCommandRunner();
        expect(
          runner.run(const <String>['custom-devices', 'list']),
          throwsToolExit(message: featureNotEnabledMessage),
        );
      }
    );

    testUsingContext(
      'custom-devices reset command fails when feature is not enabled',
      () async {
        final CommandRunner<void> runner = createCustomDevicesCommandRunner();
        expect(
          runner.run(const <String>['custom-devices', 'reset']),
          throwsToolExit(message: featureNotEnabledMessage),
        );
      }
    );

    // test add command
    testUsingContext(
      'custom-devices add command correctly adds ssh device config on linux',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: 'testhostname',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'y',
            screenshot: 'testscreenshot',
            apply: 'y'
          ),
          fileSystem: fs,
          processManager: FakeProcessManager.any(),
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: const <String>[
                'ping',
                '-c', '1',
                '-w', '1',
                'testhostname',
              ],
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: const <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                r'${localPath}',
                r'testuser@testhostname:/tmp/${appName}',
              ],
              uninstallCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testrundebug',
              ],
              forwardPortCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-o', 'ExitOnForwardFailure=yes',
                '-L', r'127.0.0.1:${hostPort}:127.0.0.1:${devicePort}',
                'testuser@testhostname',
                "echo 'Port forwarding success'; read",
              ],
              forwardPortSuccessRegex: RegExp('Port forwarding success'),
              screenshotCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testscreenshot',
              ],
            )
          )
        );
      }
    );

    testUsingContext(
      'custom-devices add command correctly adds ipv4 ssh device config',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: '192.168.178.1',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'y',
            screenshot: 'testscreenshot',
            apply: 'y',
          ),
          processManager: FakeProcessManager.any(),
          fileSystem: fs,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: const <String>[
                'ping',
                '-c', '1',
                '-w', '1',
                '192.168.178.1',
              ],
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: const <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                r'${localPath}',
                r'testuser@192.168.178.1:/tmp/${appName}',
              ],
              uninstallCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@192.168.178.1',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@192.168.178.1',
                'testrundebug',
              ],
              forwardPortCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-o', 'ExitOnForwardFailure=yes',
                '-L', r'127.0.0.1:${hostPort}:127.0.0.1:${devicePort}',
                'testuser@192.168.178.1',
                "echo 'Port forwarding success'; read",
              ],
              forwardPortSuccessRegex: RegExp('Port forwarding success'),
              screenshotCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@192.168.178.1',
                'testscreenshot',
              ],
            ),
          ),
        );
      },
    );

    testUsingContext(
      'custom-devices add command correctly adds ipv6 ssh device config',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: '::1',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'y',
            screenshot: 'testscreenshot',
            apply: 'y',
          ),
          fileSystem: fs,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: const <String>[
                'ping',
                '-6',
                '-c', '1',
                '-w', '1',
                '::1',
              ],
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: const <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                '-6',
                r'${localPath}',
                r'testuser@[::1]:/tmp/${appName}',
              ],
              uninstallCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-6',
                'testuser@[::1]',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-6',
                'testuser@[::1]',
                'testrundebug',
              ],
              forwardPortCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-o', 'ExitOnForwardFailure=yes',
                '-6',
                '-L', r'[::1]:${hostPort}:[::1]:${devicePort}',
                'testuser@[::1]',
                "echo 'Port forwarding success'; read",
              ],
              forwardPortSuccessRegex: RegExp('Port forwarding success'),
              screenshotCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-6',
                'testuser@[::1]',
                'testscreenshot',
              ],
            ),
          ),
        );
      },
    );

    testUsingContext(
      'custom-devices add command correctly adds non-forwarding ssh device config',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: 'testhostname',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'n',
            screenshot: 'testscreenshot',
            apply: 'y',
          ),
          fileSystem: fs,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            const CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: <String>[
                'ping',
                '-c', '1',
                '-w', '1',
                'testhostname',
              ],
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                r'${localPath}',
                r'testuser@testhostname:/tmp/${appName}',
              ],
              uninstallCommand: <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testrundebug',
              ],
              screenshotCommand: <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testscreenshot',
              ],
            ),
          ),
        );
      },
    );

    testUsingContext(
      'custom-devices add command correctly adds non-screenshotting ssh device config',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: 'testhostname',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'y',
            screenshot: '',
            apply: 'y',
          ),
          fileSystem: fs,
          featureEnabled: true,
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes,
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: const <String>[
                'ping',
                '-c', '1',
                '-w', '1',
                'testhostname',
              ],
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: const <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                r'${localPath}',
                r'testuser@testhostname:/tmp/${appName}',
              ],
              uninstallCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testrundebug',
              ],
              forwardPortCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-o', 'ExitOnForwardFailure=yes',
                '-L', r'127.0.0.1:${hostPort}:127.0.0.1:${devicePort}',
                'testuser@testhostname',
                "echo 'Port forwarding success'; read",
              ],
              forwardPortSuccessRegex: RegExp('Port forwarding success'),
            )
          )
        );
      }
    );

    testUsingContext(
      'custom-devices delete command deletes device and creates backup',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test(),
        );

        config.add(CustomDeviceConfig.exampleUnix.copyWith(id: 'testid'));

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          config: (_, __) => config,
          fileSystem: fs,
          featureEnabled: true
        );

        final Uint8List contentsBefore = fs.file('.flutter_custom_devices.json').readAsBytesSync();

        await expectLater(
          runner.run(const <String>['custom-devices', 'delete', '-d', 'testid']),
          completes
        );
        expect(fs.file('/.flutter_custom_devices.json.bak'), exists);
        expect(config.devices, hasLength(0));

        final Uint8List backupContents = fs.file('.flutter_custom_devices.json.bak').readAsBytesSync();
        expect(contentsBefore, equals(backupContents));
      }
    );

    testUsingContext(
      'custom-devices delete command without device argument throws tool exit',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test(),
        );
        config.add(CustomDeviceConfig.exampleUnix.copyWith(id: 'testid2'));
        final Uint8List contentsBefore = fs.file('.flutter_custom_devices.json').readAsBytesSync();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          featureEnabled: true
        );
        await expectLater(
          runner.run(const <String>['custom-devices', 'delete']),
          throwsToolExit()
        );

        final Uint8List contentsAfter = fs.file('.flutter_custom_devices.json').readAsBytesSync();
        expect(contentsBefore, equals(contentsAfter));
        expect(fs.file('.flutter_custom_devices.json.bak').existsSync(), isFalse);
      }
    );

    testUsingContext(
      'custom-devices delete command throws tool exit with invalid device id',
      () async {
        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          featureEnabled: true
        );
        await expectLater(
          runner.run(const <String>['custom-devices', 'delete', '-d', 'testid']),
          throwsToolExit(message: 'Couldn\'t find device with id "testid" in config at "/.flutter_custom_devices.json"')
        );
      }
    );

    testUsingContext(
      'custom-devices list command throws tool exit when config contains errors',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();
        final BufferLogger logger = BufferLogger.test();

        fs.file('.flutter_custom_devices.json').writeAsStringSync('{"custom-devices": {}}');

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          fileSystem: fs,
          logger: logger,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'list']),
          throwsToolExit(message: 'Could not list custom devices.')
        );
        expect(
          logger.errorText,
          contains("Could not load custom devices config. config['custom-devices'] is not a JSON array.")
        );
      }
    );

    testUsingContext(
      'custom-devices list command prints message when no devices found',
      () async {
        final BufferLogger logger = BufferLogger.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'list']),
          completes
        );
        expect(
          logger.statusText,
          contains('No custom devices found in "/.flutter_custom_devices.json"')
        );
      }
    );

    testUsingContext(
      'custom-devices list command lists all devices',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();
        final BufferLogger logger = BufferLogger.test();

        CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: logger,
        )..add(
          CustomDeviceConfig.exampleUnix.copyWith(id: 'testid', label: 'testlabel', enabled: true)
        )..add(
          CustomDeviceConfig.exampleUnix.copyWith(id: 'testid2', label: 'testlabel2', enabled: false)
        );

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          fileSystem: fs,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'list']),
          completes
        );
        expect(
          logger.statusText,
          contains('List of custom devices in "/.flutter_custom_devices.json":')
        );
        expect(
          logger.statusText,
          contains('id: testid, label: testlabel, enabled: true')
        );
        expect(
          logger.statusText,
          contains('id: testid2, label: testlabel2, enabled: false')
        );
      }
    );

    testUsingContext(
      'custom-devices reset correctly backs up the config file',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();
        final BufferLogger logger = BufferLogger.test();

        CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: logger,
        )..add(
          CustomDeviceConfig.exampleUnix.copyWith(id: 'testid', label: 'testlabel', enabled: true)
        )..add(
          CustomDeviceConfig.exampleUnix.copyWith(id: 'testid2', label: 'testlabel2', enabled: false)
        );

        final Uint8List contentsBefore = fs.file('.flutter_custom_devices.json').readAsBytesSync();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          fileSystem: fs,
          featureEnabled: true
        );
        await expectLater(
          runner.run(const <String>['custom-devices', 'reset']),
          completes
        );
        expect(
          logger.statusText,
          contains(
            'Successfully resetted the custom devices config file and created a '
            'backup at "/.flutter_custom_devices.json.bak".'
          )
        );

        final Uint8List backupContents = fs.file('.flutter_custom_devices.json.bak').readAsBytesSync();
        expect(contentsBefore, equals(backupContents));
        expect(
          fs.file('.flutter_custom_devices.json').readAsStringSync(),
          anyOf(equals(defaultConfigLinux1), equals(defaultConfigLinux2))
        );
      }
    );

    testUsingContext(
      "custom-devices reset outputs correct msg when config file didn't exist",
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test();
        final BufferLogger logger = BufferLogger.test();

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          logger: logger,
          fileSystem: fs,
          featureEnabled: true
        );
        await expectLater(
          runner.run(const <String>['custom-devices', 'reset']),
          completes
        );
        expect(
          logger.statusText,
          contains(
            'Successfully resetted the custom devices config file.'
          )
        );

        expect(fs.file('.flutter_custom_devices.json.bak'), isNot(exists));
        expect(
          fs.file('.flutter_custom_devices.json').readAsStringSync(),
          anyOf(equals(defaultConfigLinux1), equals(defaultConfigLinux2))
        );
      }
    );
  });

  group('windows', () {
    setUp(() {
      Cache.flutterRoot = windowsFlutterRoot;
    });

    testUsingContext(
      'custom-devices add command correctly adds ssh device config on windows',
      () async {
        final MemoryFileSystem fs = MemoryFileSystem.test(style: FileSystemStyle.windows);

        final CommandRunner<void> runner = createCustomDevicesCommandRunner(
          terminal: (Platform platform) => createFakeTerminalForAddingSshDevice(
            platform: platform,
            id: 'testid',
            label: 'testlabel',
            sdkNameAndVersion: 'testsdknameandversion',
            enabled: 'y',
            hostname: 'testhostname',
            username: 'testuser',
            runDebug: 'testrundebug',
            usePortForwarding: 'y',
            screenshot: 'testscreenshot',
            apply: 'y',
          ),
          fileSystem: fs,
          platform: windowsPlatform,
          featureEnabled: true
        );

        await expectLater(
          runner.run(const <String>['custom-devices', 'add', '--no-check']),
          completes
        );

        final CustomDevicesConfig config = CustomDevicesConfig.test(
          fileSystem: fs,
          directory: fs.directory('/'),
          logger: BufferLogger.test()
        );

        expect(
          config.devices,
          contains(
            CustomDeviceConfig(
              id: 'testid',
              label: 'testlabel',
              sdkNameAndVersion: 'testsdknameandversion',
              enabled: true,
              pingCommand: const <String>[
                'ping',
                '-n', '1',
                '-w', '500',
                'testhostname',
              ],
              pingSuccessRegex: RegExp(r'[<=]\d+ms'),
              postBuildCommand: null, // ignore: avoid_redundant_argument_values
              installCommand: const <String>[
                'scp',
                '-r',
                '-o', 'BatchMode=yes',
                r'${localPath}',
                r'testuser@testhostname:/tmp/${appName}',
              ],
              uninstallCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                r'rm -rf "/tmp/${appName}"',
              ],
              runDebugCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testrundebug',
              ],
              forwardPortCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                '-o', 'ExitOnForwardFailure=yes',
                '-L', r'127.0.0.1:${hostPort}:127.0.0.1:${devicePort}',
                'testuser@testhostname',
                "echo 'Port forwarding success'; read",
              ],
              forwardPortSuccessRegex: RegExp('Port forwarding success'),
              screenshotCommand: const <String>[
                'ssh',
                '-o', 'BatchMode=yes',
                'testuser@testhostname',
                'testscreenshot',
              ],
            ),
          ),
        );
      },
    );
  });
}
