// 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 'package:async/async.dart';
import 'package:meta/meta.dart';
import 'package:process/process.dart';

import '../base/common.dart';
import '../base/error_handling_io.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/terminal.dart';
import '../convert.dart';
import '../custom_devices/custom_device.dart';
import '../custom_devices/custom_device_config.dart';
import '../custom_devices/custom_devices_config.dart';
import '../device_port_forwarder.dart';
import '../features.dart';
import '../runner/flutter_command.dart';

/// just the function signature of the [print] function.
/// The Object arg may be null.
typedef PrintFn = void Function(Object);

class CustomDevicesCommand extends FlutterCommand {
  factory CustomDevicesCommand({
    required CustomDevicesConfig customDevicesConfig,
    required OperatingSystemUtils operatingSystemUtils,
    required Terminal terminal,
    required Platform platform,
    required ProcessManager processManager,
    required FileSystem fileSystem,
    required Logger logger,
    required FeatureFlags featureFlags,
  }) {
    return CustomDevicesCommand._common(
      customDevicesConfig: customDevicesConfig,
      operatingSystemUtils: operatingSystemUtils,
      terminal: terminal,
      platform: platform,
      processManager: processManager,
      fileSystem: fileSystem,
      logger: logger,
      featureFlags: featureFlags
    );
  }

  @visibleForTesting
  factory CustomDevicesCommand.test({
    required CustomDevicesConfig customDevicesConfig,
    required OperatingSystemUtils operatingSystemUtils,
    required Terminal terminal,
    required Platform platform,
    required ProcessManager processManager,
    required FileSystem fileSystem,
    required Logger logger,
    required FeatureFlags featureFlags,
    PrintFn usagePrintFn = print
  }) {
    return CustomDevicesCommand._common(
      customDevicesConfig: customDevicesConfig,
      operatingSystemUtils: operatingSystemUtils,
      terminal: terminal,
      platform: platform,
      processManager: processManager,
      fileSystem: fileSystem,
      logger: logger,
      featureFlags: featureFlags,
      usagePrintFn: usagePrintFn
    );
  }

  CustomDevicesCommand._common({
    required CustomDevicesConfig customDevicesConfig,
    required OperatingSystemUtils operatingSystemUtils,
    required Terminal terminal,
    required Platform platform,
    required ProcessManager processManager,
    required FileSystem fileSystem,
    required Logger logger,
    required FeatureFlags featureFlags,
    PrintFn usagePrintFn = print,
  }) : _customDevicesConfig = customDevicesConfig,
       _featureFlags = featureFlags,
       _usagePrintFn = usagePrintFn
  {
    addSubcommand(CustomDevicesListCommand(
      customDevicesConfig: customDevicesConfig,
      featureFlags: featureFlags,
      logger: logger,
    ));
    addSubcommand(CustomDevicesResetCommand(
      customDevicesConfig: customDevicesConfig,
      featureFlags: featureFlags,
      fileSystem: fileSystem,
      logger: logger,
    ));
    addSubcommand(CustomDevicesAddCommand(
      customDevicesConfig: customDevicesConfig,
      operatingSystemUtils: operatingSystemUtils,
      terminal: terminal,
      platform: platform,
      featureFlags: featureFlags,
      processManager: processManager,
      fileSystem: fileSystem,
      logger: logger,
    ));
    addSubcommand(CustomDevicesDeleteCommand(
      customDevicesConfig: customDevicesConfig,
      featureFlags: featureFlags,
      fileSystem: fileSystem,
      logger: logger,
    ));
  }

  final CustomDevicesConfig _customDevicesConfig;
  final FeatureFlags _featureFlags;
  final void Function(Object) _usagePrintFn;

  @override
  String get description {
    String configFileLine;
    if (_featureFlags.areCustomDevicesEnabled) {
      configFileLine = '\nMakes changes to the config file at "${_customDevicesConfig.configPath}".\n';
    } else {
      configFileLine = '';
    }

    return '''
List, reset, add and delete custom devices.
$configFileLine
This is just a collection of commonly used shorthands for things like adding
ssh devices, resetting (with backup) and checking the config file. For advanced
configuration or more complete documentation, edit the config file with an
editor that supports JSON schemas like VS Code.

Requires the custom devices feature to be enabled. You can enable it using "flutter config --enable-custom-devices".
''';
  }

  @override
  String get name => 'custom-devices';

  @override
  String get category => FlutterCommandCategory.tools;

  @override
  Future<FlutterCommandResult> runCommand() async {
    return FlutterCommandResult.success();
  }

  @override
  void printUsage() {
    _usagePrintFn(usage);
  }
}

/// This class is meant to provide some commonly used utility functions
/// to the subcommands, like backing up the config file & checking if the
/// feature is enabled.
abstract class CustomDevicesCommandBase extends FlutterCommand {
  CustomDevicesCommandBase({
    required this.customDevicesConfig,
    required this.featureFlags,
    required this.fileSystem,
    required this.logger,
  });

  @protected final CustomDevicesConfig customDevicesConfig;
  @protected final FeatureFlags featureFlags;
  @protected final FileSystem? fileSystem;
  @protected final Logger logger;

  /// The path to the (potentially non-existing) backup of the config file.
  @protected
  String get configBackupPath => '${customDevicesConfig.configPath}.bak';

  /// Copies the current config file to [configBackupPath], overwriting it
  /// if necessary. Returns false and does nothing if the current config file
  /// doesn't exist. (True otherwise)
  @protected
  bool backup() {
    final File configFile = fileSystem!.file(customDevicesConfig.configPath);
    if (configFile.existsSync()) {
      configFile.copySync(configBackupPath);
      return true;
    }
    return false;
  }

  /// Checks if the custom devices feature is enabled and returns true/false
  /// accordingly. Additionally, logs an error if it's not enabled with a hint
  /// on how to enable it.
  @protected
  void checkFeatureEnabled() {
    if (!featureFlags.areCustomDevicesEnabled) {
      throwToolExit(
        'Custom devices feature must be enabled. '
        'Enable using `flutter config --enable-custom-devices`.'
      );
    }
  }
}

class CustomDevicesListCommand extends CustomDevicesCommandBase {
  CustomDevicesListCommand({
    required super.customDevicesConfig,
    required super.featureFlags,
    required super.logger,
  }) : super(
         fileSystem: null
       );

  @override
  String get description => '''
List the currently configured custom devices, both enabled and disabled, reachable or not.
''';

  @override
  String get name => 'list';

  @override
  Future<FlutterCommandResult> runCommand() async {
    checkFeatureEnabled();

    late List<CustomDeviceConfig> devices;
    try {
      devices = customDevicesConfig.devices;
    } on Exception {
      throwToolExit('Could not list custom devices.');
    }

    if (devices.isEmpty) {
      logger.printStatus('No custom devices found in "${customDevicesConfig.configPath}"');
    } else {
      logger.printStatus('List of custom devices in "${customDevicesConfig.configPath}":');
      for (final CustomDeviceConfig device in devices) {
        logger.printStatus('id: ${device.id}, label: ${device.label}, enabled: ${device.enabled}', indent: 2, hangingIndent: 2);
      }
    }

    return FlutterCommandResult.success();
  }
}

class CustomDevicesResetCommand extends CustomDevicesCommandBase {
  CustomDevicesResetCommand({
    required super.customDevicesConfig,
    required super.featureFlags,
    required FileSystem super.fileSystem,
    required super.logger,
  });

  @override
  String get description => '''
Reset the config file to the default.

The current config file will be backed up to the same path, but with a `.bak` appended.
If a file already exists at the backup location, it will be overwritten.
''';

  @override
  String get name => 'reset';

  @override
  Future<FlutterCommandResult> runCommand() async {
    checkFeatureEnabled();

    final bool wasBackedUp = backup();

    ErrorHandlingFileSystem.deleteIfExists(fileSystem!.file(customDevicesConfig.configPath));
    customDevicesConfig.ensureFileExists();

    logger.printStatus(
        wasBackedUp
        ? 'Successfully resetted the custom devices config file and created a '
          'backup at "$configBackupPath".'
        : 'Successfully resetted the custom devices config file.'
    );
    return FlutterCommandResult.success();
  }
}

class CustomDevicesAddCommand extends CustomDevicesCommandBase {
  CustomDevicesAddCommand({
    required super.customDevicesConfig,
    required OperatingSystemUtils operatingSystemUtils,
    required Terminal terminal,
    required Platform platform,
    required super.featureFlags,
    required ProcessManager processManager,
    required FileSystem super.fileSystem,
    required super.logger,
  }) : _operatingSystemUtils = operatingSystemUtils,
       _terminal = terminal,
       _platform = platform,
       _processManager = processManager
  {
    argParser.addFlag(
      _kCheck,
      help:
        'Make sure the config actually works. This will execute some of the '
        'commands in the config (if necessary with dummy arguments). This '
        'flag is enabled by default when "--json" is not specified. If '
        '"--json" is given, it is disabled by default.\n'
        'For example, a config with "null" as the "runDebug" command is '
        'invalid. If the "runDebug" command is valid (so it is an array of '
        'strings) but the command is not found (because you have a typo, for '
        'example), the config won\'t work and "--check" will spot that.'
    );

    argParser.addOption(
      _kJson,
      help:
        'Add the custom device described by this JSON-encoded string to the '
        'list of custom-devices instead of using the normal, interactive way '
        'of configuring. Useful if you want to use the "flutter custom-devices '
        'add" command from a script, or use it non-interactively for some '
        'other reason.\n'
        "By default, this won't check whether the passed in config actually "
        'works. For more info see the "--check" option.',
      valueHelp: '{"id": "pi", ...}',
      aliases: _kJsonAliases
    );

    argParser.addFlag(
      _kSsh,
      help:
        'Add a ssh-device. This will automatically fill out some of the config '
        'options for you with good defaults, and in other cases save you some '
        "typing. So you'll only need to enter some things like hostname and "
        'username of the remote device instead of entering each individual '
        'command.',
      defaultsTo: true,
      negatable: false
    );
  }

  static const String _kJson = 'json';
  static const List<String> _kJsonAliases = <String>['js'];
  static const String _kCheck = 'check';
  static const String _kSsh = 'ssh';

  // A hostname consists of one or more "names", separated by a dot.
  // A name may consist of alpha-numeric characters. Hyphens are also allowed,
  // but not as the first or last character of the name.
  static final RegExp _hostnameRegex = RegExp(r'^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$');

  final OperatingSystemUtils _operatingSystemUtils;
  final Terminal _terminal;
  final Platform _platform;
  final ProcessManager _processManager;
  late StreamQueue<String> inputs;

  @override
  String get description => 'Add a new device the custom devices config file.';

  @override
  String get name => 'add';

  void _printConfigCheckingError(String err) {
    logger.printError(err);
  }

  /// Check this config by executing some of the commands, see if they run
  /// fine.
  Future<bool> _checkConfigWithLogging(final CustomDeviceConfig config) async {
    final CustomDevice device = CustomDevice(
      config: config,
      logger: logger,
      processManager: _processManager
    );

    bool result = true;

    try {
      final bool reachable = await device.tryPing();
      if (!reachable) {
        _printConfigCheckingError("Couldn't ping device.");
        result = false;
      }
    } on Exception catch (e) {
      _printConfigCheckingError('While executing ping command: $e');
      result = false;
    }

    final Directory temp = await fileSystem!.systemTempDirectory.createTemp();

    try {
      final bool ok = await device.tryInstall(
        localPath: temp.path,
        appName: temp.basename
      );
      if (!ok) {
        _printConfigCheckingError("Couldn't install test app on device.");
        result = false;
      }
    } on Exception catch (e) {
      _printConfigCheckingError('While executing install command: $e');
      result = false;
    }

    await temp.delete();

    try {
      final bool ok = await device.tryUninstall(appName: temp.basename);
      if (!ok) {
        _printConfigCheckingError("Couldn't uninstall test app from device.");
        result = false;
      }
    } on Exception catch (e) {
      _printConfigCheckingError('While executing uninstall command: $e');
      result = false;
    }

    if (config.usesPortForwarding) {
      final CustomDevicePortForwarder portForwarder = CustomDevicePortForwarder(
        deviceName: device.name,
        forwardPortCommand: config.forwardPortCommand!,
        forwardPortSuccessRegex: config.forwardPortSuccessRegex!,
        processManager: _processManager,
        logger: logger,
      );

      try {
        // find a random port we can forward
        final int port = await _operatingSystemUtils.findFreePort();

        final ForwardedPort? forwardedPort = await portForwarder.tryForward(port, port);
        if (forwardedPort == null) {
          _printConfigCheckingError("Couldn't forward test port $port from device.",);
          result = false;
        } else {
          await portForwarder.unforward(forwardedPort);
        }
      } on Exception catch (e) {
        _printConfigCheckingError(
          'While forwarding/unforwarding device port: $e',
        );
        result = false;
      }
    }

    if (result) {
      logger.printStatus('Passed all checks successfully.');
    }

    return result;
  }

  /// Run non-interactively (useful if running from scripts or bots),
  /// add value of the `--json` arg to the config.
  ///
  /// Only check if `--check` is explicitly specified. (Don't check by default)
  Future<FlutterCommandResult> runNonInteractively() async {
    final String jsonStr = stringArgDeprecated(_kJson)!;
    final bool shouldCheck = boolArgDeprecated(_kCheck);

    dynamic json;
    try {
      json = jsonDecode(jsonStr);
    } on FormatException catch (e) {
      throwToolExit('Could not decode json: $e');
    }

    late CustomDeviceConfig config;
    try {
      config = CustomDeviceConfig.fromJson(json);
    } on CustomDeviceRevivalException catch (e) {
      throwToolExit('Invalid custom device config: $e');
    }

    if (shouldCheck && !await _checkConfigWithLogging(config)) {
      throwToolExit("Custom device didn't pass all checks.");
    }

    customDevicesConfig.add(config);
    printSuccessfullyAdded();

    return FlutterCommandResult.success();
  }

  void printSuccessfullyAdded() {
    logger.printStatus('Successfully added custom device to config file at "${customDevicesConfig.configPath}".');
  }

  bool _isValidHostname(String s) => _hostnameRegex.hasMatch(s);

  bool _isValidIpAddr(String s) => InternetAddress.tryParse(s) != null;

  /// Ask the user to input a string.
  Future<String?> askForString(
    String name, {
    String? description,
    String? example,
    String? defaultsTo,
    Future<bool> Function(String)? validator,
  }) async {
    String msg = description ?? name;

    final String exampleOrDefault = <String>[
      if (example != null) 'example: $example',
      if (defaultsTo != null) 'empty for $defaultsTo',
    ].join(', ');

    if (exampleOrDefault.isNotEmpty) {
      msg += ' ($exampleOrDefault)';
    }

    logger.printStatus(msg);
    while (true) {
      if (!await inputs.hasNext) {
        return null;
      }

      final String input = await inputs.next;

      if (validator != null && !await validator(input)) {
        logger.printStatus('Invalid input. Please enter $name:');
      } else {
        return input;
      }
    }
  }

  /// Ask the user for a y(es) / n(o) or empty input.
  Future<bool> askForBool(
    String name, {
    String? description,
    bool defaultsTo = true,
  }) async {
    final String defaultsToStr = defaultsTo == true ? '[Y/n]' : '[y/N]';
    logger.printStatus('$description $defaultsToStr (empty for default)');
    while (true) {
      final String input = await inputs.next;

      if (input.isEmpty) {
        return defaultsTo;
      } else if (input.toLowerCase() == 'y') {
        return true;
      } else if (input.toLowerCase() == 'n') {
        return false;
      } else {
        logger.printStatus('Invalid input. Expected is either y, n or empty for default. $name? $defaultsToStr');
      }
    }
  }

  /// Ask the user if he wants to apply the config.
  /// Shows a different prompt if errors or warnings exist in the config.
  Future<bool> askApplyConfig({bool hasErrorsOrWarnings = false}) {
    return askForBool(
      'apply',
      description: hasErrorsOrWarnings
        ? 'Warnings or errors exist in custom device. '
          'Would you like to add the custom device to the config anyway?'
        : 'Would you like to add the custom device to the config now?',
      defaultsTo: !hasErrorsOrWarnings
    );
  }

  /// Run interactively (with user prompts), the target device should be
  /// connected to via ssh.
  Future<FlutterCommandResult> runInteractivelySsh() async {
    final bool shouldCheck = boolArgDeprecated(_kCheck);

    // Listen to the keystrokes stream as late as possible, since it's a
    // single-subscription stream apparently.
    // Also, _terminal.keystrokes can be closed unexpectedly, which will result
    // in StreamQueue.next throwing a StateError when make the StreamQueue listen
    // to that directly.
    // This caused errors when using Ctrl+C to terminate while the
    // custom-devices add command is waiting for user input.
    // So instead, we add the keystrokes stream events to a new single-subscription
    // stream and listen to that instead.
    final StreamController<String> nonClosingKeystrokes = StreamController<String>();
    final StreamSubscription<String> keystrokesSubscription = _terminal.keystrokes.listen(
      (String s) => nonClosingKeystrokes.add(s.trim()),
      cancelOnError: true
    );

    inputs = StreamQueue<String>(nonClosingKeystrokes.stream);

    final String id = (await askForString(
      'id',
      description:
        'Please enter the id you want to device to have. Must contain only '
        'alphanumeric or underscore characters.',
      example: 'pi',
      validator: (String s) async => RegExp(r'^\w+$').hasMatch(s),
    ))!;

    final String label = (await askForString(
      'label',
      description:
        'Please enter the label of the device, which is a slightly more verbose '
        'name for the device.',
      example: 'Raspberry Pi',
    ))!;

    final String sdkNameAndVersion = (await askForString(
      'SDK name and version',
      example: 'Raspberry Pi 4 Model B+',
    ))!;

    final bool enabled = await askForBool(
      'enabled',
      description: 'Should the device be enabled?',
    );

    final String targetStr = (await askForString(
      'target',
      description: 'Please enter the hostname or IPv4/v6 address of the device.',
      example: 'raspberrypi',
      validator: (String s) async => _isValidHostname(s) || _isValidIpAddr(s)
    ))!;

    final InternetAddress? targetIp = InternetAddress.tryParse(targetStr);
    final bool useIp = targetIp != null;
    final bool ipv6 = useIp && targetIp.type == InternetAddressType.IPv6;
    final InternetAddress loopbackIp = ipv6
      ? InternetAddress.loopbackIPv6
      : InternetAddress.loopbackIPv4;

    final String username = (await askForString(
      'username',
      description: 'Please enter the username used for ssh-ing into the remote device.',
      example: 'pi',
      defaultsTo: 'no username',
    ))!;

    final String remoteRunDebugCommand = (await askForString(
      'run command',
      description:
        'Please enter the command executed on the remote device for starting '
        r'the app. "/tmp/${appName}" is the path to the asset bundle.',
      example: r'flutter-pi /tmp/${appName}'
    ))!;

    final bool usePortForwarding = await askForBool(
      'use port forwarding',
      description: 'Should the device use port forwarding? '
        'Using port forwarding is the default because it works in all cases, however if your '
        'remote device has a static IP address and you have a way of '
        'specifying the "--observatory-host=<ip>" engine option, you might prefer '
        'not using port forwarding.',
    );

    final String screenshotCommand = (await askForString(
      'screenshot command',
      description: 'Enter the command executed on the remote device for taking a screenshot.',
      example: r"fbgrab /tmp/screenshot.png && cat /tmp/screenshot.png | base64 | tr -d ' \n\t'",
      defaultsTo: 'no screenshotting support',
    ))!;

    // SSH expects IPv6 addresses to use the bracket syntax like URIs do too,
    // but the IPv6 the user enters is a raw IPv6 address, so we need to wrap it.
    final String sshTarget =
      (username.isNotEmpty ? '$username@' : '')
      + (ipv6 ? '[${targetIp.address}]' : targetStr);

    final String formattedLoopbackIp = ipv6
      ? '[${loopbackIp.address}]'
      : loopbackIp.address;

    CustomDeviceConfig config = CustomDeviceConfig(
      id: id,
      label: label,
      sdkNameAndVersion: sdkNameAndVersion,
      enabled: enabled,

      // host-platform specific, filled out later
      pingCommand: const <String>[],

      postBuildCommand: const <String>[],

      // just install to /tmp/${appName} by default
      installCommand: <String>[
        'scp',
        '-r',
        '-o', 'BatchMode=yes',
        if (ipv6) '-6',
        r'${localPath}',
        '$sshTarget:/tmp/\${appName}',
      ],

      uninstallCommand: <String>[
        'ssh',
        '-o', 'BatchMode=yes',
        if (ipv6) '-6',
        sshTarget,
        r'rm -rf "/tmp/${appName}"',
      ],

      runDebugCommand: <String>[
        'ssh',
        '-o', 'BatchMode=yes',
        if (ipv6) '-6',
        sshTarget,
        remoteRunDebugCommand,
      ],

      forwardPortCommand: usePortForwarding
        ? <String>[
          'ssh',
          '-o', 'BatchMode=yes',
          '-o', 'ExitOnForwardFailure=yes',
          if (ipv6) '-6',
          '-L', '$formattedLoopbackIp:\${hostPort}:$formattedLoopbackIp:\${devicePort}',
          sshTarget,
          "echo 'Port forwarding success'; read",
        ]
        : null,
      forwardPortSuccessRegex: usePortForwarding
        ? RegExp('Port forwarding success')
        : null,

      screenshotCommand: screenshotCommand.isNotEmpty
        ? <String>[
          'ssh',
          '-o', 'BatchMode=yes',
          if (ipv6) '-6',
          sshTarget,
          screenshotCommand,
        ]
        : null
    );

    if (_platform.isWindows) {
      config = config.copyWith(
        pingCommand: <String>[
          'ping',
          if (ipv6) '-6',
          '-n', '1',
          '-w', '500',
          targetStr,
        ],
        explicitPingSuccessRegex: true,
        pingSuccessRegex: RegExp(r'[<=]\d+ms')
      );
    } else if (_platform.isLinux || _platform.isMacOS) {
      config = config.copyWith(
        pingCommand: <String>[
          'ping',
          if (ipv6) '-6',
          '-c', '1',
          '-w', '1',
          targetStr,
        ],
        explicitPingSuccessRegex: true,
      );
    } else {
      throw UnsupportedError('Unsupported operating system');
    }

    final bool apply = await askApplyConfig(
      hasErrorsOrWarnings:
        shouldCheck && !(await _checkConfigWithLogging(config))
    );

    unawaited(keystrokesSubscription.cancel());
    unawaited(nonClosingKeystrokes.close());

    if (apply) {
      customDevicesConfig.add(config);
      printSuccessfullyAdded();
    }

    return FlutterCommandResult.success();
  }

  @override
  Future<FlutterCommandResult> runCommand() async {
    checkFeatureEnabled();

    if (stringArgDeprecated(_kJson) != null) {
      return runNonInteractively();
    }
    if (boolArgDeprecated(_kSsh) == true) {
      return runInteractivelySsh();
    }
    throw UnsupportedError('Unknown run mode');
  }
}

class CustomDevicesDeleteCommand extends CustomDevicesCommandBase {
  CustomDevicesDeleteCommand({
    required super.customDevicesConfig,
    required super.featureFlags,
    required FileSystem super.fileSystem,
    required super.logger,
  });

  @override
  String get description => '''
Delete a device from the config file.
''';

  @override
  String get name => 'delete';

  @override
  Future<FlutterCommandResult> runCommand() async {
    checkFeatureEnabled();

    final String? id = globalResults!['device-id'] as String?;
    if (id == null || !customDevicesConfig.contains(id)) {
      throwToolExit('Couldn\'t find device with id "$id" in config at "${customDevicesConfig.configPath}"');
    }

    backup();
    customDevicesConfig.remove(id);
    logger.printStatus('Successfully removed device with id "$id" from config at "${customDevicesConfig.configPath}"');
    return FlutterCommandResult.success();
  }
}
