// 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 '../base/common.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../convert.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../runner/flutter_command.dart';

class DevicesCommand extends FlutterCommand {
  DevicesCommand({ bool verboseHelp = false }) {
    argParser.addFlag('machine',
      negatable: false,
      help: 'Output device information in machine readable structured JSON format.',
    );
    argParser.addOption(
      'timeout',
      abbr: 't',
      help: '(deprecated) This option has been replaced by "--${FlutterOptions.kDeviceTimeout}".',
      hide: !verboseHelp,
    );
    usesDeviceTimeoutOption();
  }

  @override
  final String name = 'devices';

  @override
  final String description = 'List all connected devices.';

  @override
  final String category = FlutterCommandCategory.tools;

  @override
  Duration? get deviceDiscoveryTimeout {
    if (argResults?['timeout'] != null) {
      final int? timeoutSeconds = int.tryParse(stringArg('timeout')!);
      if (timeoutSeconds == null) {
        throwToolExit('Could not parse -t/--timeout argument. It must be an integer.');
      }
      return Duration(seconds: timeoutSeconds);
    }
    return super.deviceDiscoveryTimeout;
  }

  @override
  Future<void> validateCommand() {
    if (argResults?['timeout'] != null) {
      globals.printWarning('${globals.logger.terminal.warningMark} The "--timeout" argument is deprecated; use "--${FlutterOptions.kDeviceTimeout}" instead.');
    }
    return super.validateCommand();
  }

  @override
  Future<FlutterCommandResult> runCommand() async {
    if (globals.doctor?.canListAnything != true) {
      throwToolExit(
        "Unable to locate a development device; please run 'flutter doctor' for "
        'information about installing additional components.',
        exitCode: 1);
    }

    final DevicesCommandOutput output = DevicesCommandOutput(
      platform: globals.platform,
      logger: globals.logger,
      deviceManager: globals.deviceManager,
      deviceDiscoveryTimeout: deviceDiscoveryTimeout,
    );

    await output.findAndOutputAllTargetDevices(
      machine: boolArg('machine'),
    );

    return FlutterCommandResult.success();
  }
}

class DevicesCommandOutput {
  factory DevicesCommandOutput({
    required Platform platform,
    required Logger logger,
    DeviceManager? deviceManager,
    Duration? deviceDiscoveryTimeout,
  }) {
    if (platform.isMacOS) {
      return DevicesCommandOutputWithExtendedWirelessDeviceDiscovery(
        logger: logger,
        deviceManager: deviceManager,
        deviceDiscoveryTimeout: deviceDiscoveryTimeout,
      );
    }
    return DevicesCommandOutput._private(
      logger: logger,
      deviceManager: deviceManager,
      deviceDiscoveryTimeout: deviceDiscoveryTimeout,
    );
  }

  DevicesCommandOutput._private({
    required Logger logger,
    required DeviceManager? deviceManager,
    required this.deviceDiscoveryTimeout,
  })  : _deviceManager = deviceManager,
        _logger = logger;

  final DeviceManager? _deviceManager;
  final Logger _logger;
  final Duration? deviceDiscoveryTimeout;

  Future<List<Device>> _getAttachedDevices(DeviceManager deviceManager) async {
    return deviceManager.getAllDevices(
      filter: DeviceDiscoveryFilter(
        deviceConnectionInterface: DeviceConnectionInterface.attached,
      ),
    );
  }

  Future<List<Device>> _getWirelessDevices(DeviceManager deviceManager) async {
    return deviceManager.getAllDevices(
      filter: DeviceDiscoveryFilter(
        deviceConnectionInterface: DeviceConnectionInterface.wireless,
      ),
    );
  }

  Future<void> findAndOutputAllTargetDevices({required bool machine}) async {
    List<Device> attachedDevices = <Device>[];
    List<Device> wirelessDevices = <Device>[];
    final DeviceManager? deviceManager = _deviceManager;
    if (deviceManager != null) {
      // Refresh the cache and then get the attached and wireless devices from
      // the cache.
      await deviceManager.refreshAllDevices(timeout: deviceDiscoveryTimeout);
      attachedDevices = await _getAttachedDevices(deviceManager);
      wirelessDevices = await _getWirelessDevices(deviceManager);
    }
    final List<Device> allDevices = attachedDevices + wirelessDevices;

    if (machine) {
      await printDevicesAsJson(allDevices);
      return;
    }

    if (allDevices.isEmpty) {
      _printNoDevicesDetected();
    } else {
      if (attachedDevices.isNotEmpty) {
        _logger.printStatus('${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
        await Device.printDevices(attachedDevices, _logger);
      }
      if (wirelessDevices.isNotEmpty) {
        if (attachedDevices.isNotEmpty) {
          _logger.printStatus('');
        }
        _logger.printStatus('${wirelessDevices.length} wirelessly connected ${pluralize('device', wirelessDevices.length)}:\n');
        await Device.printDevices(wirelessDevices, _logger);
      }
    }
    await _printDiagnostics();
  }

  void _printNoDevicesDetected() {
    final StringBuffer status = StringBuffer('No devices detected.');
    status.writeln();
    status.writeln();
    status.writeln('Run "flutter emulators" to list and start any available device emulators.');
    status.writeln();
    status.write('If you expected your device to be detected, please run "flutter doctor" to diagnose potential issues. ');
    if (deviceDiscoveryTimeout == null) {
      status.write('You may also try increasing the time to wait for connected devices with the --${FlutterOptions.kDeviceTimeout} flag. ');
    }
    status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');

    _logger.printStatus(status.toString());
  }

  Future<void> _printDiagnostics() async {
    final List<String> diagnostics = await _deviceManager?.getDeviceDiagnostics() ?? <String>[];
    if (diagnostics.isNotEmpty) {
      _logger.printStatus('');
      for (final String diagnostic in diagnostics) {
        _logger.printStatus('• $diagnostic', hangingIndent: 2);
      }
    }
  }

  Future<void> printDevicesAsJson(List<Device> devices) async {
    _logger.printStatus(
      const JsonEncoder.withIndent('  ').convert(
        await Future.wait(devices.map((Device d) => d.toJson()))
      )
    );
  }
}

const String _checkingForWirelessDevicesMessage = 'Checking for wireless devices...';
const String _noAttachedCheckForWireless = 'No devices found yet. Checking for wireless devices...';
const String _noWirelessDevicesFoundMessage = 'No wireless devices were found.';

class DevicesCommandOutputWithExtendedWirelessDeviceDiscovery extends DevicesCommandOutput {
  DevicesCommandOutputWithExtendedWirelessDeviceDiscovery({
    required super.logger,
    super.deviceManager,
    super.deviceDiscoveryTimeout,
  }) : super._private();

  @override
  Future<void> findAndOutputAllTargetDevices({required bool machine}) async {
    // When a user defines the timeout, use the super function that does not do
    // longer wireless device discovery.
    if (deviceDiscoveryTimeout != null) {
      return super.findAndOutputAllTargetDevices(machine: machine);
    }

    if (machine) {
      final List<Device> devices = await _deviceManager?.refreshAllDevices(
        filter: DeviceDiscoveryFilter(),
        timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout,
      ) ?? <Device>[];
      await printDevicesAsJson(devices);
      return;
    }

    final Future<void>? extendedWirelessDiscovery = _deviceManager?.refreshExtendedWirelessDeviceDiscoverers(
      timeout: DeviceManager.minimumWirelessDeviceDiscoveryTimeout,
    );

    List<Device> attachedDevices = <Device>[];
    final DeviceManager? deviceManager = _deviceManager;
    if (deviceManager != null) {
      attachedDevices = await _getAttachedDevices(deviceManager);
    }

    // Number of lines to clear starts at 1 because it's inclusive of the line
    // the cursor is on, which will be blank for this use case.
    int numLinesToClear = 1;

    // Display list of attached devices.
    if (attachedDevices.isNotEmpty) {
      _logger.printStatus('${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
      await Device.printDevices(attachedDevices, _logger);
      _logger.printStatus('');
      numLinesToClear += 1;
    }

    // Display waiting message.
    if (attachedDevices.isEmpty) {
      _logger.printStatus(_noAttachedCheckForWireless);
    } else {
      _logger.printStatus(_checkingForWirelessDevicesMessage);
    }
    numLinesToClear += 1;

    final Status waitingStatus = _logger.startSpinner();
    await extendedWirelessDiscovery;
    List<Device> wirelessDevices = <Device>[];
    if (deviceManager != null) {
      wirelessDevices = await _getWirelessDevices(deviceManager);
    }
    waitingStatus.stop();

    final Terminal terminal = _logger.terminal;
    if (_logger.isVerbose) {
      // Reprint the attach devices.
      if (attachedDevices.isNotEmpty) {
        _logger.printStatus('\n${attachedDevices.length} connected ${pluralize('device', attachedDevices.length)}:\n');
        await Device.printDevices(attachedDevices, _logger);
      }
    } else if (terminal.supportsColor && terminal is AnsiTerminal) {
      _logger.printStatus(
        terminal.clearLines(numLinesToClear),
        newline: false,
      );
    }

    if (attachedDevices.isNotEmpty || !_logger.terminal.supportsColor) {
      _logger.printStatus('');
    }

    if (wirelessDevices.isEmpty) {
      if (attachedDevices.isEmpty) {
        // No wireless or attached devices were found.
        _printNoDevicesDetected();
      } else {
        // Attached devices found, wireless devices not found.
        _logger.printStatus(_noWirelessDevicesFoundMessage);
      }
    } else {
      // Display list of wireless devices.
      _logger.printStatus('${wirelessDevices.length} wirelessly connected ${pluralize('device', wirelessDevices.length)}:\n');
      await Device.printDevices(wirelessDevices, _logger);
    }
    await _printDiagnostics();
  }
}
