// 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:file/src/backends/memory/memory_file_system.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import 'package:device_doctor/src/android_device.dart';
import 'package:device_doctor/src/device.dart';
import 'package:device_doctor/src/health.dart';
import 'package:device_doctor/src/utils.dart';

import 'utils.dart';

void main() {
  group('AndroidDeviceDiscovery', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    List<List<int>> output;
    Process process;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('deviceDiscovery no retries', () async {
      StringBuffer sb = StringBuffer();
      sb.writeln('List of devices attached');
      sb.writeln('ZY223JQNMR      device');
      output = <List<int>>[utf8.encode(sb.toString())];
      process = FakeProcess(0, out: output);
      when(processManager.start(any, workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      List<Device> devices = await deviceDiscovery.discoverDevices(
          retryDuration: const Duration(seconds: 0), processManager: processManager);
      expect(devices.length, equals(1));
      expect(devices[0].deviceId, equals('ZY223JQNMR'));
    });

    test('deviceDiscovery fails', () async {
      when(processManager.start(any, workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => throw TimeoutException('test'));
      expect(deviceDiscovery.discoverDevices(retryDuration: const Duration(seconds: 0), processManager: processManager),
          throwsA(TypeMatcher<BuildFailedError>()));
    });
  });

  group('AndroidDeviceProperties', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process property_process;
    Process process;
    String output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns empty when no device is attached', () async {
      output = 'List of devices attached';
      process = FakeProcess(0, out: <List<int>>[utf8.encode(output)]);

      when(processManager.start(<Object>['adb', 'devices', '-l'], workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      expect(await deviceDiscovery.deviceProperties(processManager: processManager), equals(<String, String>{}));
    });

    test('get device properties', () async {
      output = '''[ro.product.brand]: [abc]
      [ro.build.id]: [def]
      [ro.build.type]: [ghi]
      [ro.product.model]: [jkl]
      [ro.product.board]: [mno]
      ''';
      property_process = FakeProcess(0, out: <List<int>>[utf8.encode(output)]);

      when(processManager.start(<Object>['adb', '-s', 'ZY223JQNMR', 'shell', 'getprop'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(property_process));

      Map<String, String> deviceProperties = await deviceDiscovery
          .getDeviceProperties(AndroidDevice(deviceId: 'ZY223JQNMR'), processManager: processManager);

      const Map<String, String> expectedProperties = <String, String>{
        'product_brand': 'abc',
        'build_id': 'def',
        'build_type': 'ghi',
        'product_model': 'jkl',
        'product_board': 'mno'
      };
      expect(deviceProperties, equals(expectedProperties));
    });
  });

  group('AndroidAdbPowerServiceCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when adb power service is available', () async {
      process = FakeProcess(0);
      when(processManager
              .start(<Object>['adb', 'shell', 'dumpsys', 'power'], workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.adbPowerServiceCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kAdbPowerServiceCheckKey);
    });

    test('returns failure when adb returns none 0 code', () async {
      process = FakeProcess(1);
      when(processManager
              .start(<Object>['adb', 'shell', 'dumpsys', 'power'], workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.adbPowerServiceCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kAdbPowerServiceCheckKey);
      expect(healthCheckResult.details, 'Executable adb failed with exit code 1.');
    });
  });

  group('AndroidDevloperModeCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;
    List<List<int>> output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when developer mode is on', () async {
      output = <List<int>>[utf8.encode('1')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'global', 'development_settings_enabled'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.developerModeCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kDeveloperModeCheckKey);
    });

    test('returns failure when developer mode is off', () async {
      output = <List<int>>[utf8.encode('0')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'global', 'development_settings_enabled'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.developerModeCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kDeveloperModeCheckKey);
      expect(healthCheckResult.details, 'developer mode is off');
    });

    test('returns success when screensaver is off', () async {
      output = <List<int>>[utf8.encode('0')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'secure', 'screensaver_enabled'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenSaverCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kScreenSaverCheckKey);
    });

    test('returns failure when screensaver is on', () async {
      output = <List<int>>[utf8.encode('1')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'secure', 'screensaver_enabled'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenSaverCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kScreenSaverCheckKey);
      expect(healthCheckResult.details, 'Screensaver is on');
    });

    test('returns failure when adb return none 0 code', () async {
      process = FakeProcess(1);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'global', 'development_settings_enabled'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.developerModeCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kDeveloperModeCheckKey);
      expect(healthCheckResult.details, 'Executable adb failed with exit code 1.');
    });
  });

  group('AndroidScreenOnCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;
    List<List<int>> output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when screen is on', () async {
      const String screenMessage = '''
      mHoldingDisplaySuspendBlocker=true
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(
              <Object>['adb', 'shell', 'dumpsys', 'power', '|', 'grep', 'mHoldingDisplaySuspendBlocker'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenOnCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kScreenOnCheckKey);
    });

    test('returns failure when screen is off', () async {
      const String screenMessage = '''
      mHoldingDisplaySuspendBlocker=false
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(
              <Object>['adb', 'shell', 'dumpsys', 'power', '|', 'grep', 'mHoldingDisplaySuspendBlocker'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenOnCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kScreenOnCheckKey);
      expect(healthCheckResult.details, 'screen is off');
    });

    test('returns failure when adb return non 0 code', () async {
      process = FakeProcess(1);
      when(processManager.start(
              <Object>['adb', 'shell', 'dumpsys', 'power', '|', 'grep', 'mHoldingDisplaySuspendBlocker'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenOnCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kScreenOnCheckKey);
      expect(healthCheckResult.details, 'Executable adb failed with exit code 1.');
    });
  });

  group('AndroidScreenRotationCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;
    List<List<int>> output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when rotation is disabled', () async {
      output = <List<int>>[utf8.encode('0')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'system', 'accelerometer_rotation'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenRotationCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kScreenRotationCheckKey);
    });

    test('returns failure when screen rotation is enabled', () async {
      output = <List<int>>[utf8.encode('1')];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'settings', 'get', 'system', 'accelerometer_rotation'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.screenRotationCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kScreenRotationCheckKey);
      expect(healthCheckResult.details, 'Screen rotation is enabled');
    });
  });

  group('AndroidDeviceKillProcesses', () {
    late AndroidDevice device;
    late MockProcessManager processManager;
    Process listProcess;
    Process killProcess;
    List<List<int>>? output;

    setUp(() {
      device = AndroidDevice(deviceId: 'abc');
      processManager = MockProcessManager();
    });

    test('successfully killed running processes', () async {
      output = <List<int>>[
        utf8.encode('Proc #27: fg     T/ /TOP  LCM  t: 0 0:com.google.android.apps.nexuslauncher/u0a199 (top-activity)')
      ];
      listProcess = FakeProcess(0, out: output);
      killProcess = FakeProcess(0);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'activity', '|', 'grep', 'top-activity'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(listProcess));
      when(processManager.start(<Object>['adb', 'shell', 'am', 'force-stop', 'com.google.android.apps.nexuslauncher'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(killProcess));

      final bool result = await device.killProcesses(processManager: processManager);
      expect(result, true);
    });

    test('no running processes', () async {
      output = <List<int>>[];
      listProcess = FakeProcess(0, out: output);
      killProcess = FakeProcess(0);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'activity', '|', 'grep', 'top-activity'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(listProcess));
      when(processManager.start(<Object>['adb', 'shell', 'am', 'force-stop', 'com.google.android.apps.nexuslauncher'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(killProcess));

      final bool result = await device.killProcesses(processManager: processManager);
      expect(result, true);
    });

    test('fails to kill running processes', () async {
      output = <List<int>>[
        utf8.encode('Proc #27: fg     T/ /TOP  LCM  t: 0 0:com.google.android.apps.nexuslauncher/u0a199 (top-activity)')
      ];
      listProcess = FakeProcess(0, out: output);
      killProcess = FakeProcess(1);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'activity', '|', 'grep', 'top-activity'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(listProcess));
      when(processManager.start(<Object>['adb', 'shell', 'am', 'force-stop', 'com.google.android.apps.nexuslauncher'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(killProcess));

      final bool result = await device.killProcesses(processManager: processManager);
      expect(result, false);
    });
  });

  group('KillAdbServerCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when adb power service is killed', () async {
      process = FakeProcess(0);
      when(processManager.start(<Object>['adb', 'kill-server'], workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.killAdbServerCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kKillAdbServerCheckKey);
    });

    test('returns failure when adb returns non 0 code', () async {
      process = FakeProcess(1);
      when(processManager.start(<Object>['adb', 'kill-server'], workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.killAdbServerCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kKillAdbServerCheckKey);
      expect(healthCheckResult.details, 'Executable adb failed with exit code 1.');
    });
  });

  group('BatteryLevelCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;
    List<List<int>> output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when battery level is high', () async {
      const String screenMessage = '''
  level: 100
  mod level: -1
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'battery', '|', 'grep', 'level'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.batteryLevelCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kBatteryLevelCheckKey);
    });

    test('returns failure when battery level is below threshold', () async {
      const String screenMessage = '''
  level: 10
  mod level: -1
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'battery', '|', 'grep', 'level'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult = await deviceDiscovery.batteryLevelCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kBatteryLevelCheckKey);
      expect(healthCheckResult.details, 'Battery level (10) is below 15');
    });
  });

  group('BatteryTemperatureCheck', () {
    late AndroidDeviceDiscovery deviceDiscovery;
    late MockProcessManager processManager;
    Process process;
    List<List<int>> output;

    setUp(() {
      deviceDiscovery = AndroidDeviceDiscovery(MemoryFileSystem().file('output'));
      processManager = MockProcessManager();
    });

    test('returns success when battery temperature is low', () async {
      const String screenMessage = '''
  temperature: 24
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'battery', '|', 'grep', 'temperature'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult =
          await deviceDiscovery.batteryTemperatureCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, true);
      expect(healthCheckResult.name, kBatteryTemperatureCheckKey);
    });

    test('returns failure when battery temperature is above threshold', () async {
      const String screenMessage = '''
  temperature: 350
      ''';
      output = <List<int>>[utf8.encode(screenMessage)];
      process = FakeProcess(0, out: output);
      when(processManager.start(<Object>['adb', 'shell', 'dumpsys', 'battery', '|', 'grep', 'temperature'],
              workingDirectory: anyNamed('workingDirectory')))
          .thenAnswer((_) => Future.value(process));

      HealthCheckResult healthCheckResult =
          await deviceDiscovery.batteryTemperatureCheck(processManager: processManager);
      expect(healthCheckResult.succeeded, false);
      expect(healthCheckResult.name, kBatteryTemperatureCheckKey);
      expect(healthCheckResult.details, 'Battery temperature (35°C) is over 34°C');
    });
  });
}
