// 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/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
import '../device.dart';
import '../globals.dart' as globals;
import 'adb.dart';
import 'android_device.dart';
import 'android_sdk.dart';
import 'android_workflow.dart' hide androidWorkflow;
import 'android_workflow.dart' as workflow show androidWorkflow;

/// Device discovery for Android physical devices and emulators.s
class AndroidDevices extends PollingDeviceDiscovery {
  // TODO(jonahwilliams): make these required after google3 is updated.
  AndroidDevices({
    AndroidWorkflow androidWorkflow,
    ProcessManager processManager,
    Logger logger,
    AndroidSdk androidSdk,
  }) : _androidWorkflow = androidWorkflow ?? workflow.androidWorkflow,
       _androidSdk = androidSdk ?? globals.androidSdk,
       _processUtils = ProcessUtils(
         logger: logger ?? globals.logger,
         processManager: processManager ?? globals.processManager,
        ),
       super('Android devices');

  final AndroidWorkflow _androidWorkflow;
  final ProcessUtils _processUtils;
  final AndroidSdk _androidSdk;

  @override
  bool get supportsPlatform => true;

  @override
  bool get canListAnything => _androidWorkflow.canListDevices;

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

  @override
  Future<List<String>> getDiagnostics() async {
    final String adbPath = getAdbPath(_androidSdk);
    if (adbPath == null) {
      return <String>[];
    }

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

  // 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.
  @visibleForTesting
  static 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'],
          ));
        }
      } else {
        diagnostics?.add(
          'Unexpected failure parsing device information from adb output:\n'
          '$line\n'
          'Please report a bug at https://github.com/flutter/flutter/issues/new/choose');
      }
    }
  }
}
