// Copyright 2020 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 'dart:convert';
import 'dart:io';

import 'package:meta/meta.dart';
import 'package:process/process.dart';
import 'package:retry/retry.dart';

import 'device.dart';
import 'health.dart';
import 'host_utils.dart';
import 'mac.dart';
import 'utils.dart';

// The minimum battery level to run a task with a scale of 100%.
const int _kBatteryMinLevel = 15;
// The maximum battery temprature to run a task with a Celsius degree.
const int _kBatteryMaxTemperatureInCelsius = 34;

class AndroidDeviceDiscovery implements DeviceDiscovery {
  factory AndroidDeviceDiscovery(File? output) {
    return _instance ??= AndroidDeviceDiscovery._(output);
  }

  final File? _outputFilePath;
  AndroidDeviceDiscovery._(this._outputFilePath);

  @visibleForTesting
  AndroidDeviceDiscovery.testing(this._outputFilePath);

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

  static AndroidDeviceDiscovery? _instance;

  Future<String> _deviceListOutput(Duration timeout, {ProcessManager? processManager}) async {
    return eval('adb', <String>['devices', '-l'], canFail: false, processManager: processManager).timeout(timeout);
  }

  Future<List<String>> _deviceListOutputWithRetries(Duration retryDuration, {ProcessManager? processManager}) async {
    const Duration deviceOutputTimeout = Duration(seconds: 15);
    RetryOptions r = RetryOptions(
      maxAttempts: 3,
      delayFactor: retryDuration,
    );
    return await r.retry(
      () async {
        String result = await _deviceListOutput(deviceOutputTimeout, processManager: processManager);
        return result.trim().split('\n');
      },
      retryIf: (Exception e) => e is TimeoutException,
      onRetry: (Exception e) => _killAdbServer(processManager: processManager),
    );
  }

  void _killAdbServer({ProcessManager? processManager}) async {
    if (Platform.isWindows) {
      await killAllRunningProcessesOnWindows('adb', processManager: processManager);
    } else {
      await eval('adb', <String>['kill-server'], canFail: false, processManager: processManager);
    }
  }

  @override
  Future<List<AndroidDevice>> discoverDevices(
      {Duration retryDuration = const Duration(seconds: 10), ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    List<String> output = await _deviceListOutputWithRetries(retryDuration, processManager: processManager);
    List<String> results = <String>[];
    for (String line in output) {
      // Skip lines like: * daemon started successfully *
      if (line.startsWith('* daemon ')) continue;

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

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

        String? deviceID = match?[1];
        String? deviceState = match?[2];

        if (!const ['unauthorized', 'offline'].contains(deviceState)) {
          results.add(deviceID!);
        }
      } else {
        throw 'Failed to parse device from adb output: $line';
      }
    }
    return results.map((String id) => AndroidDevice(deviceId: id)).toList();
  }

  @override
  Future<Map<String, List<HealthCheckResult>>> checkDevices({ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    final List<HealthCheckResult> defaultChecks = <HealthCheckResult>[];
    defaultChecks.add(await killAdbServerCheck(processManager: processManager));
    final Map<String, List<HealthCheckResult>> results = <String, List<HealthCheckResult>>{};
    for (AndroidDevice device in await discoverDevices(processManager: processManager)) {
      final List<HealthCheckResult> checks = defaultChecks;
      checks.add(HealthCheckResult.success(kDeviceAccessCheckKey));
      checks.add(await adbPowerServiceCheck(processManager: processManager));
      checks.add(await developerModeCheck(processManager: processManager));
      checks.add(await screenOnCheck(processManager: processManager));
      checks.add(await screenSaverCheck(processManager: processManager));
      checks.add(await screenRotationCheck(processManager: processManager));
      checks.add(await batteryLevelCheck(processManager: processManager));
      checks.add(await batteryTemperatureCheck(processManager: processManager));
      if (Platform.isMacOS) {
        checks.add(await userAutoLoginCheck(processManager: processManager));
      }
      results['android-device-${device.deviceId}'] = checks;
    }
    final Map<String, Map<String, dynamic>> healthCheckMap = await healthcheck(results);
    writeToFile(json.encode(healthCheckMap), _outputFilePath!);
    return results;
  }

  /// Checks and returns the device properties, like manufacturer, base_buildid, etc.
  ///
  /// It supports multiple devices, but here we are assuming only one device is attached.
  @override
  Future<Map<String, String>> deviceProperties({ProcessManager? processManager}) async {
    final List<AndroidDevice> devices = await discoverDevices(processManager: processManager);
    Map<String, String> properties = <String, String>{};
    if (devices.isEmpty) {
      writeToFile(json.encode(properties), _outputFilePath!);
      logger.info('No device is available.');
      return properties;
    }
    properties = await getDeviceProperties(devices[0], processManager: processManager);
    final String propertiesJson = json.encode(properties);

    writeToFile(propertiesJson, _outputFilePath!);
    logger.info('Properties for deviceID ${devices[0].deviceId}: $propertiesJson');
    return properties;
  }

  /// Gets android device properties based on swarming bot configuration.
  ///
  /// Refer function `get_dimensions` from
  /// https://source.chromium.org/chromium/infra/infra/+/master:luci/appengine/swarming/swarming_bot/api/platforms/android.py
  Future<Map<String, String>> getDeviceProperties(AndroidDevice device, {ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    final Map<String, String> deviceProperties = <String, String>{};
    final Map<String, String> propertyMap = <String, String>{};
    LineSplitter.split(
            await eval('adb', <String>['-s', device.deviceId!, 'shell', 'getprop'], processManager: processManager))
        .forEach((String property) {
      final List<String> propertyList = property.replaceAll('[', '').replaceAll(']', '').split(': ');

      /// Deal with entries spanning only one line.
      ///
      /// This is to skip unused entries spanninning multiple lines.
      /// For example:
      ///   [persist.sys.boot.reason.history]: [reboot,ota,1613677289
      ///   reboot,userrequested,1613677269
      ///   reboot,userrequested,1613508544]
      if (propertyList.length == 2) {
        propertyMap[propertyList[0].trim()] = propertyList[1].trim();
      }
    });

    deviceProperties['product_brand'] = propertyMap['ro.product.brand']!;
    deviceProperties['build_id'] = propertyMap['ro.build.id']!;
    deviceProperties['build_type'] = propertyMap['ro.build.type']!;
    deviceProperties['product_model'] = propertyMap['ro.product.model']!;
    deviceProperties['product_board'] = propertyMap['ro.product.board']!;
    return deviceProperties;
  }

  @override
  Future<void> recoverDevices() async {
    for (Device device in await discoverDevices()) {
      await device.recover();
    }
  }

  @visibleForTesting
  Future<HealthCheckResult> adbPowerServiceCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      await eval('adb', <String>['shell', 'dumpsys', 'power'], processManager: processManager);
      healthCheckResult = HealthCheckResult.success(kAdbPowerServiceCheckKey);
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kAdbPowerServiceCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting

  /// The health check for Android device screen on.
  ///
  /// An Android device screen is on when both `mHoldingWakeLockSuspendBlocker` and
  /// `mHoldingDisplaySuspendBlocker` are true.
  Future<HealthCheckResult> screenOnCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String result = await eval(
          'adb', <String>['shell', 'dumpsys', 'power', '|', 'grep', 'mHoldingDisplaySuspendBlocker'],
          processManager: processManager);
      if (result.trim() == 'mHoldingDisplaySuspendBlocker=true') {
        healthCheckResult = HealthCheckResult.success(kScreenOnCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kScreenOnCheckKey, 'screen is off');
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kScreenOnCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting

  /// The health check for Android device adb kill server.
  ///
  /// Kill adb server before running any health check to avoid device quarantine:
  /// https://github.com/flutter/flutter/issues/93075.
  Future<HealthCheckResult> killAdbServerCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      await eval('adb', <String>['kill-server'], processManager: processManager);
      healthCheckResult = HealthCheckResult.success(kKillAdbServerCheckKey);
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kKillAdbServerCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting

  /// The health check for Android device developer mode.
  ///
  /// Developer mode `on` is expected for a healthy Android device.
  Future<HealthCheckResult> developerModeCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String result = await eval(
          'adb', <String>['shell', 'settings', 'get', 'global', 'development_settings_enabled'],
          processManager: processManager);
      // The output of `development_settings_enabled` is `1` when developer mode is on.
      if (result == '1') {
        healthCheckResult = HealthCheckResult.success(kDeveloperModeCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kDeveloperModeCheckKey, 'developer mode is off');
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kDeveloperModeCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  /// The health check to validate screen rotation is off.
  ///
  /// Screen rotation is expected disabled for a healthy Android device.
  Future<HealthCheckResult> screenRotationCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String result = await eval('adb', <String>['shell', 'settings', 'get', 'system', 'accelerometer_rotation'],
          processManager: processManager);
      // The output of `screensaver_enabled` is `0` when screensaver mode is off.
      if (result == '0') {
        healthCheckResult = HealthCheckResult.success(kScreenRotationCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kScreenRotationCheckKey, 'Screen rotation is enabled');
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kScreenRotationCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  /// The health check to validate screensaver is off.
  ///
  /// Screensaver`off` is expected for a healthy Android device.
  Future<HealthCheckResult> screenSaverCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String result = await eval('adb', <String>['shell', 'settings', 'get', 'secure', 'screensaver_enabled'],
          processManager: processManager);
      // The output of `screensaver_enabled` is `0` when screensaver mode is off.
      if (result == '0') {
        healthCheckResult = HealthCheckResult.success(kScreenSaverCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kScreenSaverCheckKey, 'Screensaver is on');
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kScreenSaverCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  /// The health check for battery level.
  Future<HealthCheckResult> batteryLevelCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      // The battery level returns two rows. For example:
      //   level: 100
      //   mod level: -1
      final String levelResults = await eval('adb', <String>['shell', 'dumpsys', 'battery', '|', 'grep', 'level'],
          processManager: processManager);
      final RegExp levelRegExp = RegExp('level: (?<level>.+)');
      final RegExpMatch? match = levelRegExp.firstMatch(levelResults);
      final int level = int.parse(match!.namedGroup('level')!);
      if (level < _kBatteryMinLevel) {
        healthCheckResult =
            HealthCheckResult.failure(kBatteryLevelCheckKey, 'Battery level ($level) is below $_kBatteryMinLevel');
      } else {
        healthCheckResult = HealthCheckResult.success(kBatteryLevelCheckKey);
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kScreenSaverCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  /// The health check for battery temperature.
  Future<HealthCheckResult> batteryTemperatureCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      // The battery temperature returns one row. For example:
      //  temperature: 240
      // It means 24°C.
      final String tempResult = await eval('adb', <String>['shell', 'dumpsys', 'battery', '|', 'grep', 'temperature'],
          processManager: processManager);
      final RegExp? tempRegExp = RegExp('temperature: (?<temperature>.+)');
      final RegExpMatch match = tempRegExp!.firstMatch(tempResult)!;
      final int temperature = int.parse(match.namedGroup('temperature')!);
      if (temperature > _kBatteryMaxTemperatureInCelsius * 10) {
        healthCheckResult = HealthCheckResult.failure(kBatteryTemperatureCheckKey,
            'Battery temperature (${(temperature * 0.1).toInt()}°C) is over $_kBatteryMaxTemperatureInCelsius°C');
      } else {
        healthCheckResult = HealthCheckResult.success(kBatteryTemperatureCheckKey);
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kBatteryTemperatureCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @override
  Future<void> prepareDevices() async {
    for (Device device in await discoverDevices()) {
      await device.prepare();
    }
  }
}

class AndroidDevice implements Device {
  AndroidDevice({@required this.deviceId});

  @override
  final String? deviceId;

  @override
  Future<void> recover() async {
    await eval('adb', <String>['-s', deviceId!, 'reboot'], canFail: false);
  }

  @override
  Future<void> prepare() async {
    await killProcesses();
  }

  /// Kill top running process if existing.
  @visibleForTesting
  Future<bool> killProcesses({ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    String result;
    result = await eval('adb', <String>['shell', 'dumpsys', 'activity', '|', 'grep', 'top-activity'],
        canFail: true, processManager: processManager);

    // Skip uninstalling process when no device is available or no application exists.
    if (result == 'adb: no devices/emulators found' || result.isEmpty) {
      stdout.write('no process is running');
      return true;
    }
    final List<String> results = result.trim().split('\n');
    // Example result:
    //
    // Proc # 0: fore  T/A/T  trm: 0 4544:com.google.android.googlequicksearchbox/u0a66 (top-activity)
    final List<String> processes =
        results.map((result) => result.substring(result.lastIndexOf(':') + 1, result.lastIndexOf('/'))).toList();
    try {
      for (String process in processes) {
        await eval('adb', <String>['shell', 'am', 'force-stop', process], processManager: processManager);
        stdout.write('adb stop process: $process');
      }
    } on BuildFailedError catch (error) {
      stderr.write('uninstall applications fails: $error');
      return false;
    }
    return true;
  }
}
