// 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' show LineSplitter, json;
import 'dart:io';

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

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

/// The minimum battery level to run a task with a scale of 100%.
const int _kBatteryMinLevel = 15;

/// Identifiers for devices that should never be rebooted.
final Set<String> noRebootList = <String>{
  '822ef7958bba573829d85eef4df6cbdd86593730', // 32bit iPhone requires manual intervention on reboot.
};

/// IOS implementation of [DeviceDiscovery].
///
/// Discovers available ios devices and chooses one to work with.
class IosDeviceDiscovery implements DeviceDiscovery {
  factory IosDeviceDiscovery(File? output) {
    return _instance ??= IosDeviceDiscovery._(output);
  }

  final File? _outputFilePath;

  IosDeviceDiscovery._(this._outputFilePath);

  @visibleForTesting
  IosDeviceDiscovery.testing(this._outputFilePath);

  static IosDeviceDiscovery? _instance;

  @override
  Future<List<Device>> discoverDevices({Duration retryDuration = const Duration(seconds: 10)}) async {
    return LineSplitter.split(await deviceListOutput()).map((String id) => IosDevice(deviceId: id)).toList();
  }

  Future<String> deviceListOutput({
    ProcessManager processManager = const LocalProcessManager(),
  }) async {
    final String fullPathIdeviceId = await getMacBinaryPath('idevice_id', processManager: processManager);
    return eval(fullPathIdeviceId, <String>['-l'], processManager: processManager);
  }

  @override
  Future<Map<String, List<HealthCheckResult>>> checkDevices({ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    final Map<String, List<HealthCheckResult>> results = <String, List<HealthCheckResult>>{};
    for (Device device in await discoverDevices()) {
      final List<HealthCheckResult> checks = <HealthCheckResult>[];
      checks.add(HealthCheckResult.success(kDeviceAccessCheckKey));
      checks.add(await keychainUnlockCheck(processManager: processManager));
      checks.add(await certCheck(processManager: processManager));
      checks.add(await devicePairCheck(processManager: processManager));
      checks.add(await userAutoLoginCheck(processManager: processManager));
      checks.add(await deviceProvisioningProfileCheck(device.deviceId, processManager: processManager));
      checks.add(await batteryLevelCheck(processManager: processManager));
      results['ios-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.
  @override
  Future<Map<String, String>> deviceProperties({ProcessManager? processManager}) async {
    return <String, String>{};
  }

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

  @visibleForTesting
  Future<HealthCheckResult> deviceProvisioningProfileCheck(String? deviceId, {ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String? homeDir = Platform.environment['HOME'];
      final String profile = await eval('ls', <String>['$homeDir/Library/MobileDevice/Provisioning\ Profiles'],
          processManager: processManager);
      final String provisionFileContent = await eval(
          'security', <String>['cms', '-D', '-i', '$homeDir/Library/MobileDevice/Provisioning\ Profiles/$profile'],
          processManager: processManager);
      if (provisionFileContent.contains(deviceId!)) {
        healthCheckResult = HealthCheckResult.success(kDeviceProvisioningProfileCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(
            kDeviceProvisioningProfileCheckKey, 'device does not exist in the provisioning profile');
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kDeviceProvisioningProfileCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting
  Future<HealthCheckResult> keychainUnlockCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      await eval(kUnlockLoginKeychain, <String>[], processManager: processManager);
      healthCheckResult = HealthCheckResult.success(kKeychainUnlockCheckKey);
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kKeychainUnlockCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting
  Future<HealthCheckResult> batteryLevelCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String batteryCheckResult = await eval(
          'ideviceinfo', <String>['-q', 'com.apple.mobile.battery', '-k', 'BatteryCurrentCapacity'],
          processManager: processManager);
      final int level = int.parse(batteryCheckResult.isEmpty ? '0' : batteryCheckResult);
      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(kBatteryLevelCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting
  Future<HealthCheckResult> certCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String certCheckResult =
          await eval('security', <String>['find-identity', '-p', 'codesigning', '-v'], processManager: processManager);
      if (certCheckResult.contains('Apple Development: Flutter Devicelab') &&
          certCheckResult.contains('1 valid identities found') &&
          !certCheckResult.contains('CSSMERR_TP_CERT_REVOKED')) {
        healthCheckResult = HealthCheckResult.success(kCertCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kCertCheckKey, certCheckResult);
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kCertCheckKey, error.toString());
    }
    return healthCheckResult;
  }

  @visibleForTesting
  Future<HealthCheckResult> devicePairCheck({ProcessManager? processManager}) async {
    HealthCheckResult healthCheckResult;
    try {
      final String devicePairCheckResult =
          await eval('idevicepair', <String>['validate'], processManager: processManager);
      if (devicePairCheckResult.contains('SUCCESS')) {
        healthCheckResult = HealthCheckResult.success(kDevicePairCheckKey);
      } else {
        healthCheckResult = HealthCheckResult.failure(kDevicePairCheckKey, devicePairCheckResult);
      }
    } on BuildFailedError catch (error) {
      healthCheckResult = HealthCheckResult.failure(kDevicePairCheckKey, error.toString());
    }
    return healthCheckResult;
  }

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

/// iOS device.
class IosDevice implements Device {
  const IosDevice({@required this.deviceId});

  @override
  final String? deviceId;

  @override
  Future<void> recover() async {
    await uninstall_applications();
    await restart_device();
  }

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

  /// Restart iOS device.
  @visibleForTesting
  Future<bool> restart_device({ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    try {
      if (noRebootList.contains(deviceId)) {
        return true;
      }
      final String fullPathIdevicediagnostics =
          await getMacBinaryPath('idevicediagnostics', processManager: processManager);
      await eval(fullPathIdevicediagnostics, <String>['restart'], processManager: processManager);
    } on BuildFailedError catch (error) {
      stderr.write('device restart fails: $error');
      return false;
    }
    return true;
  }

  /// Uninstall applications from a device.
  ///
  /// This is to prevent application installation failure caused by using different siging
  /// certificate from previous installed application.
  /// Issue: https://github.com/flutter/flutter/issues/76896
  @visibleForTesting
  Future<bool> uninstall_applications({ProcessManager? processManager}) async {
    processManager ??= LocalProcessManager();
    String result;
    final String fullPathIdeviceInstaller = await getMacBinaryPath('ideviceinstaller', processManager: processManager);
    try {
      result = await eval(fullPathIdeviceInstaller, <String>['-l'], processManager: processManager);
    } on BuildFailedError catch (error) {
      stderr.write('list applications fails: $error');
      return false;
    }

    // Skip uninstalling process when no device is available or no application exists.
    if (result == 'No device found.' || result == 'CFBundleIdentifier, CFBundleVersion, CFBundleDisplayName') {
      return true;
    }
    final List<String> results = result.trim().split('\n');
    final List<String> bundleIdentifiers = results.sublist(1).map((e) => e.split(',')[0].trim()).toList();
    try {
      for (String bundleIdentifier in bundleIdentifiers) {
        await eval(fullPathIdeviceInstaller, <String>['-U', bundleIdentifier], processManager: processManager);
      }
    } on BuildFailedError catch (error) {
      stderr.write('uninstall applications fails: $error');
      return false;
    }
    return true;
  }
}
