// 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 '../base/common.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() {
    argParser.addFlag('machine',
      negatable: false,
      help: 'Output device information in machine readable structured JSON format',
    );
    argParser.addOption(
      'timeout',
      abbr: 't',
      defaultsTo: null,
      help: 'Time in seconds to wait for devices to attach. Longer timeouts may be necessary for networked devices.'
    );
  }

  @override
  final String name = 'devices';

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

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

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

    final List<Device> devices = await globals.deviceManager.refreshAllConnectedDevices(timeout: timeout);

    if (boolArg('machine')) {
      await printDevicesAsJson(devices);
    } else {
      if (devices.isEmpty) {
        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 (timeout == null) {
          status.write('You may also try increasing the time to wait for connected devices with the --timeout flag. ');
        }
        status.write('Visit https://flutter.dev/setup/ for troubleshooting tips.');

        globals.printStatus(status.toString());
      } else {
        globals.printStatus('${devices.length} connected ${pluralize('device', devices.length)}:\n');
        await Device.printDevices(devices);
      }
      await _printDiagnostics();
    }
    return FlutterCommandResult.success();
  }

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

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