// 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 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 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()))
      )
    );
  }
}
