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

import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/user_messages.dart';
import '../device.dart';
import 'adb.dart';
import 'android_device.dart';
import 'android_sdk.dart';
import 'android_workflow.dart';

/// Device discovery for Android physical devices and emulators.
///
/// This class primarily delegates to the `adb` command line tool provided by
/// the Android SDK to discover instances of connected android devices.
///
/// See also:
///   * [AndroidDevice], the type of discovered device.
class AndroidDevices extends PollingDeviceDiscovery {
  AndroidDevices({
    @required AndroidWorkflow androidWorkflow,
    @required ProcessManager processManager,
    @required Logger logger,
    @required AndroidSdk androidSdk,
    @required FileSystem fileSystem,
    @required Platform platform,
    @required UserMessages userMessages,
  }) : _androidWorkflow = androidWorkflow,
       _androidSdk = androidSdk,
       _processUtils = ProcessUtils(
         logger: logger,
         processManager: processManager,
        ),
        _processManager = processManager,
        _logger = logger,
        _fileSystem = fileSystem,
        _platform = platform,
        _userMessages = userMessages,
        super('Android devices');

  final AndroidWorkflow _androidWorkflow;
  final ProcessUtils _processUtils;
  final AndroidSdk _androidSdk;
  final ProcessManager _processManager;
  final Logger _logger;
  final FileSystem _fileSystem;
  final Platform _platform;
  final UserMessages _userMessages;

  @override
  bool get supportsPlatform => _androidWorkflow.appliesToHostPlatform;

  @override
  bool get canListAnything => _androidWorkflow.canListDevices;

  @override
  Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
    if (_doesNotHaveAdb()) {
      return <AndroidDevice>[];
    }
    String text;
    try {
      text = (await _processUtils.run(<String>[_androidSdk.adbPath, 'devices', '-l'],
        throwOnError: true,
      )).stdout.trim();
    } on ProcessException catch (exception) {
      throwToolExit(
        'Unable to run "adb", check your Android SDK installation and '
        '$kAndroidSdkRoot environment variable: ${exception.executable}',
      );
    }
    final List<AndroidDevice> devices = <AndroidDevice>[];
    _parseADBDeviceOutput(
      text,
      devices: devices,
    );
    return devices;
  }

  @override
  Future<List<String>> getDiagnostics() async {
    if (_doesNotHaveAdb()) {
      return <String>[];
    }

    final RunResult result = await _processUtils.run(<String>[_androidSdk.adbPath, 'devices', '-l']);
    if (result.exitCode != 0) {
      return <String>[];
    }
    final List<String> diagnostics = <String>[];
    _parseADBDeviceOutput(
      result.stdout,
      diagnostics: diagnostics,
    );
    return diagnostics;
  }

  bool _doesNotHaveAdb() {
    return _androidSdk == null ||
      _androidSdk.adbPath == null ||
      !_processManager.canRun(_androidSdk.adbPath);
  }

  // 015d172c98400a03       device usb:340787200X product:nakasi model:Nexus_7 device:grouper
  static final RegExp _kDeviceRegex = RegExp(r'^(\S+)\s+(\S+)(.*)');

  /// Parse the given `adb devices` output in [text], and fill out the given list
  /// of devices and possible device issue diagnostics. Either argument can be null,
  /// in which case information for that parameter won't be populated.
  void _parseADBDeviceOutput(
    String text, {
    List<AndroidDevice> devices,
    List<String> diagnostics,
  }) {
    // Check for error messages from adb
    if (!text.contains('List of devices')) {
      diagnostics?.add(text);
      return;
    }

    for (final String line in text.trim().split('\n')) {
      // Skip lines like: * daemon started successfully *
      if (line.startsWith('* daemon ')) {
        continue;
      }

      // Skip lines about adb server and client version not matching
      if (line.startsWith(RegExp(r'adb server (version|is out of date)'))) {
        diagnostics?.add(line);
        continue;
      }

      if (line.startsWith('List of devices')) {
        continue;
      }

      if (_kDeviceRegex.hasMatch(line)) {
        final Match match = _kDeviceRegex.firstMatch(line);

        final String deviceID = match[1];
        final String deviceState = match[2];
        String rest = match[3];

        final Map<String, String> info = <String, String>{};
        if (rest != null && rest.isNotEmpty) {
          rest = rest.trim();
          for (final String data in rest.split(' ')) {
            if (data.contains(':')) {
              final List<String> fields = data.split(':');
              info[fields[0]] = fields[1];
            }
          }
        }

        if (info['model'] != null) {
          info['model'] = cleanAdbDeviceName(info['model']);
        }

        if (deviceState == 'unauthorized') {
          diagnostics?.add(
            'Device $deviceID is not authorized.\n'
            'You might need to check your device for an authorization dialog.'
          );
        } else if (deviceState == 'offline') {
          diagnostics?.add('Device $deviceID is offline.');
        } else {
          devices?.add(AndroidDevice(
            deviceID,
            productID: info['product'],
            modelID: info['model'] ?? deviceID,
            deviceCodeName: info['device'],
            androidSdk: _androidSdk,
            fileSystem: _fileSystem,
            logger: _logger,
            platform: _platform,
            processManager: _processManager,
          ));
        }
      } else {
        diagnostics?.add(
          'Unexpected failure parsing device information from adb output:\n'
          '$line\n'
          '${_userMessages.flutterToolBugInstructions}');
      }
    }
  }
}
