// 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 'dart:async';

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

import '../artifacts.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../ios/core_devices.dart';
import '../ios/devices.dart';
import '../ios/ios_deploy.dart';
import '../ios/iproxy.dart';
import '../ios/mac.dart';
import '../ios/xcode_debug.dart';
import '../reporting/reporting.dart';
import 'xcode.dart';

class XCDeviceEventNotification {
  XCDeviceEventNotification(
    this.eventType,
    this.eventInterface,
    this.deviceIdentifier,
  );

  final XCDeviceEvent eventType;
  final XCDeviceEventInterface eventInterface;
  final String deviceIdentifier;
}

enum XCDeviceEvent {
  attach,
  detach,
}

enum XCDeviceEventInterface {
  usb(name: 'usb', connectionInterface: DeviceConnectionInterface.attached),
  wifi(name: 'wifi', connectionInterface: DeviceConnectionInterface.wireless);

  const XCDeviceEventInterface({
    required this.name,
    required this.connectionInterface,
  });

  final String name;
  final DeviceConnectionInterface connectionInterface;
}

/// A utility class for interacting with Xcode xcdevice command line tools.
class XCDevice {
  XCDevice({
    required Artifacts artifacts,
    required Cache cache,
    required ProcessManager processManager,
    required Logger logger,
    required Xcode xcode,
    required Platform platform,
    required IProxy iproxy,
    required FileSystem fileSystem,
    required Analytics analytics,
    @visibleForTesting
    IOSCoreDeviceControl? coreDeviceControl,
    XcodeDebug? xcodeDebug,
  }) : _processUtils = ProcessUtils(logger: logger, processManager: processManager),
      _logger = logger,
      _iMobileDevice = IMobileDevice(
        artifacts: artifacts,
        cache: cache,
        logger: logger,
        processManager: processManager,
      ),
      _iosDeploy = IOSDeploy(
        artifacts: artifacts,
        cache: cache,
        logger: logger,
        platform: platform,
        processManager: processManager,
      ),
      _coreDeviceControl = coreDeviceControl ?? IOSCoreDeviceControl(
        logger: logger,
        processManager: processManager,
        xcode: xcode,
        fileSystem: fileSystem,
      ),
      _xcodeDebug = xcodeDebug ?? XcodeDebug(
        logger: logger,
        processManager: processManager,
        xcode: xcode,
        fileSystem: fileSystem,
      ),
      _iProxy = iproxy,
      _xcode = xcode,
      _analytics = analytics {

    _setupDeviceIdentifierByEventStream();
  }

  void dispose() {
    _usbDeviceObserveProcess?.kill();
    _wifiDeviceObserveProcess?.kill();
    _usbDeviceWaitProcess?.kill();
    _wifiDeviceWaitProcess?.kill();
  }

  final ProcessUtils _processUtils;
  final Logger _logger;
  final IMobileDevice _iMobileDevice;
  final IOSDeploy _iosDeploy;
  final Xcode _xcode;
  final IProxy _iProxy;
  final IOSCoreDeviceControl _coreDeviceControl;
  final XcodeDebug _xcodeDebug;
  final Analytics _analytics;

  List<Object>? _cachedListResults;

  Process? _usbDeviceObserveProcess;
  Process? _wifiDeviceObserveProcess;
  StreamController<XCDeviceEventNotification>? _observeStreamController;

  @visibleForTesting
  StreamController<XCDeviceEventNotification>? waitStreamController;

  Process? _usbDeviceWaitProcess;
  Process? _wifiDeviceWaitProcess;

  void _setupDeviceIdentifierByEventStream() {
    // _observeStreamController Should always be available for listeners
    // in case polling needs to be stopped and restarted.
    _observeStreamController = StreamController<XCDeviceEventNotification>.broadcast(
      onListen: _startObservingTetheredIOSDevices,
      onCancel: _stopObservingTetheredIOSDevices,
    );
  }

  bool get isInstalled => _xcode.isInstalledAndMeetsVersionCheck;

  Future<List<Object>?> _getAllDevices({
    bool useCache = false,
    required Duration timeout,
  }) async {
    if (!isInstalled) {
      _logger.printTrace("Xcode not found. Run 'flutter doctor' for more information.");
      return null;
    }
    if (useCache && _cachedListResults != null) {
      return _cachedListResults;
    }
    try {
      // USB-tethered devices should be found quickly. 1 second timeout is faster than the default.
      final RunResult result = await _processUtils.run(
        <String>[
          ..._xcode.xcrunCommand(),
          'xcdevice',
          'list',
          '--timeout',
          timeout.inSeconds.toString(),
        ],
        throwOnError: true,
      );
      if (result.exitCode == 0) {
        final String listOutput = result.stdout;
        try {
          final List<Object> listResults = (json.decode(result.stdout) as List<Object?>).whereType<Object>().toList();
          _cachedListResults = listResults;
          return listResults;
        } on FormatException {
          // xcdevice logs errors and crashes to stdout.
          _logger.printError('xcdevice returned non-JSON response: $listOutput');
          return null;
        }
      }
      _logger.printTrace('xcdevice returned an error:\n${result.stderr}');
    } on ProcessException catch (exception) {
      _logger.printTrace('Process exception running xcdevice list:\n$exception');
    } on ArgumentError catch (exception) {
      _logger.printTrace('Argument exception running xcdevice list:\n$exception');
    }

    return null;
  }

  /// Observe identifiers (UDIDs) of devices as they attach and detach.
  ///
  /// Each attach and detach event contains information on the event type,
  /// the event interface, and the device identifier.
  Stream<XCDeviceEventNotification>? observedDeviceEvents() {
    if (!isInstalled) {
      _logger.printTrace("Xcode not found. Run 'flutter doctor' for more information.");
      return null;
    }
    return _observeStreamController?.stream;
  }

  // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
  // Attach: 00008027-00192736010F802E
  // Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
  final RegExp _observationIdentifierPattern = RegExp(r'^(\w*): ([\w-]*)$');

  Future<void> _startObservingTetheredIOSDevices() async {
    try {
      if (_usbDeviceObserveProcess != null || _wifiDeviceObserveProcess != null) {
        throw Exception('xcdevice observe restart failed');
      }

      _usbDeviceObserveProcess = await _startObserveProcess(
        XCDeviceEventInterface.usb,
      );

      _wifiDeviceObserveProcess = await _startObserveProcess(
        XCDeviceEventInterface.wifi,
      );

      final Future<void> usbProcessExited = _usbDeviceObserveProcess!.exitCode.then((int status) {
        _logger.printTrace('xcdevice observe --usb exited with code $exitCode');
        // Kill other process in case only one was killed.
        _wifiDeviceObserveProcess?.kill();
      });

      final Future<void> wifiProcessExited = _wifiDeviceObserveProcess!.exitCode.then((int status) {
        _logger.printTrace('xcdevice observe --wifi exited with code $exitCode');
        // Kill other process in case only one was killed.
        _usbDeviceObserveProcess?.kill();
      });

      unawaited(Future.wait(<Future<void>>[
        usbProcessExited,
        wifiProcessExited,
      ]).whenComplete(() async {
        if (_observeStreamController?.hasListener ?? false) {
          // Tell listeners the process died.
          await _observeStreamController?.close();
        }
        _usbDeviceObserveProcess = null;
        _wifiDeviceObserveProcess = null;

        // Reopen it so new listeners can resume polling.
        _setupDeviceIdentifierByEventStream();
      }));
    } on ProcessException catch (exception, stackTrace) {
      _observeStreamController?.addError(exception, stackTrace);
    } on ArgumentError catch (exception, stackTrace) {
      _observeStreamController?.addError(exception, stackTrace);
    }
  }

  Future<Process> _startObserveProcess(XCDeviceEventInterface eventInterface) {
    // Run in interactive mode (via script) to convince
    // xcdevice it has a terminal attached in order to redirect stdout.
    return _streamXCDeviceEventCommand(
      <String>[
        'script',
        '-t',
        '0',
        '/dev/null',
        ..._xcode.xcrunCommand(),
        'xcdevice',
        'observe',
        '--${eventInterface.name}',
      ],
      prefix: 'xcdevice observe --${eventInterface.name}: ',
      mapFunction: (String line) {
        final XCDeviceEventNotification? event = _processXCDeviceStdOut(
          line,
          eventInterface,
        );
        if (event != null) {
          _observeStreamController?.add(event);
        }
        return line;
      },
    );
  }

  /// Starts the command and streams stdout/stderr from the child process to
  /// this process' stdout/stderr.
  ///
  /// If [mapFunction] is present, all lines are forwarded to [mapFunction] for
  /// further processing.
  Future<Process> _streamXCDeviceEventCommand(
    List<String> cmd, {
    String prefix = '',
    StringConverter? mapFunction,
  }) async {
    final Process process = await _processUtils.start(cmd);

    final StreamSubscription<String> stdoutSubscription = process.stdout
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        String? mappedLine = line;
        if (mapFunction != null) {
          mappedLine = mapFunction(line);
        }
        if (mappedLine != null) {
          final String message = '$prefix$mappedLine';
          _logger.printTrace(message);
        }
      });
    final StreamSubscription<String> stderrSubscription = process.stderr
      .transform<String>(utf8.decoder)
      .transform<String>(const LineSplitter())
      .listen((String line) {
        String? mappedLine = line;
        if (mapFunction != null) {
          mappedLine = mapFunction(line);
        }
        if (mappedLine != null) {
          _logger.printError('$prefix$mappedLine', wrap: false);
        }
      });

    unawaited(process.exitCode.whenComplete(() {
      stdoutSubscription.cancel();
      stderrSubscription.cancel();
    }));

    return process;
  }

  void _stopObservingTetheredIOSDevices() {
    _usbDeviceObserveProcess?.kill();
    _wifiDeviceObserveProcess?.kill();
  }

  XCDeviceEventNotification? _processXCDeviceStdOut(
    String line,
    XCDeviceEventInterface eventInterface,
  ) {
    // xcdevice observe example output of UDIDs:
    //
    // Listening for all devices, on both interfaces.
    // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
    // Attach: 00008027-00192736010F802E
    // Detach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
    // Attach: d83d5bc53967baa0ee18626ba87b6254b2ab5418
    final RegExpMatch? match = _observationIdentifierPattern.firstMatch(line);
    if (match != null && match.groupCount == 2) {
      final String verb = match.group(1)!.toLowerCase();
      final String identifier = match.group(2)!;
      if (verb.startsWith('attach')) {
        return XCDeviceEventNotification(
          XCDeviceEvent.attach,
          eventInterface,
          identifier,
        );
      } else if (verb.startsWith('detach')) {
        return XCDeviceEventNotification(
          XCDeviceEvent.detach,
          eventInterface,
          identifier,
        );
      }
    }
    return null;
  }

  /// Wait for a connect event for a specific device. Must use device's exact UDID.
  ///
  /// To cancel this process, call [cancelWaitForDeviceToConnect].
  Future<XCDeviceEventNotification?> waitForDeviceToConnect(
    String deviceId,
  ) async {
    try {
      if (_usbDeviceWaitProcess != null || _wifiDeviceWaitProcess != null) {
        throw Exception('xcdevice wait restart failed');
      }

      waitStreamController = StreamController<XCDeviceEventNotification>();

      _usbDeviceWaitProcess = await _startWaitProcess(
        deviceId,
        XCDeviceEventInterface.usb,
      );

      _wifiDeviceWaitProcess = await _startWaitProcess(
        deviceId,
        XCDeviceEventInterface.wifi,
      );

      final Future<void> usbProcessExited = _usbDeviceWaitProcess!.exitCode.then((int status) {
        _logger.printTrace('xcdevice wait --usb exited with code $exitCode');
        // Kill other process in case only one was killed.
        _wifiDeviceWaitProcess?.kill();
      });

      final Future<void> wifiProcessExited = _wifiDeviceWaitProcess!.exitCode.then((int status) {
        _logger.printTrace('xcdevice wait --wifi exited with code $exitCode');
        // Kill other process in case only one was killed.
        _usbDeviceWaitProcess?.kill();
      });

      final Future<void> allProcessesExited = Future.wait(
          <Future<void>>[
            usbProcessExited,
            wifiProcessExited,
          ]).whenComplete(() async {
        _usbDeviceWaitProcess = null;
        _wifiDeviceWaitProcess = null;
        await waitStreamController?.close();
      });

      return await Future.any(
        <Future<XCDeviceEventNotification?>>[
          allProcessesExited.then((_) => null),
          waitStreamController!.stream.first.whenComplete(() async {
            cancelWaitForDeviceToConnect();
          }),
        ],
      );
    } on ProcessException catch (exception, stackTrace) {
      _logger.printTrace('Process exception running xcdevice wait:\n$exception\n$stackTrace');
    } on ArgumentError catch (exception, stackTrace) {
      _logger.printTrace('Process exception running xcdevice wait:\n$exception\n$stackTrace');
    } on StateError {
      _logger.printTrace('Stream broke before first was found');
      return null;
    }
    return null;
  }

  Future<Process> _startWaitProcess(String deviceId, XCDeviceEventInterface eventInterface) {
    // Run in interactive mode (via script) to convince
    // xcdevice it has a terminal attached in order to redirect stdout.
    return _streamXCDeviceEventCommand(
      <String>[
        'script',
        '-t',
        '0',
        '/dev/null',
        ..._xcode.xcrunCommand(),
        'xcdevice',
        'wait',
        '--${eventInterface.name}',
        deviceId,
      ],
      prefix: 'xcdevice wait --${eventInterface.name}: ',
      mapFunction: (String line) {
        final XCDeviceEventNotification? event = _processXCDeviceStdOut(
          line,
          eventInterface,
        );
        if (event != null && event.eventType == XCDeviceEvent.attach) {
          waitStreamController?.add(event);
        }
        return line;
      },
    );
  }

  void cancelWaitForDeviceToConnect() {
    _usbDeviceWaitProcess?.kill();
    _wifiDeviceWaitProcess?.kill();
  }

  /// A list of [IOSDevice]s. This list includes connected devices and
  /// disconnected wireless devices.
  ///
  /// Sometimes devices may have incorrect connection information
  /// (`isConnected`, `connectionInterface`) if it timed out before it could get the
  /// information. Wireless devices can take longer to get the correct
  /// information.
  ///
  /// [timeout] defaults to 2 seconds.
  Future<List<IOSDevice>> getAvailableIOSDevices({ Duration? timeout }) async {
    final List<Object>? allAvailableDevices = await _getAllDevices(timeout: timeout ?? const Duration(seconds: 2));

    if (allAvailableDevices == null) {
      return const <IOSDevice>[];
    }

    final Map<String, IOSCoreDevice> coreDeviceMap = <String, IOSCoreDevice>{};
    if (_xcode.isDevicectlInstalled) {
      final List<IOSCoreDevice> coreDevices = await _coreDeviceControl.getCoreDevices();
      for (final IOSCoreDevice device in coreDevices) {
        if (device.udid == null) {
          continue;
        }
        coreDeviceMap[device.udid!] = device;
      }
    }

    // [
    //  {
    //    "simulator" : true,
    //    "operatingSystemVersion" : "13.3 (17K446)",
    //    "available" : true,
    //    "platform" : "com.apple.platform.appletvsimulator",
    //    "modelCode" : "AppleTV5,3",
    //    "identifier" : "CBB5E1ED-2172-446E-B4E7-F2B5823DBBA6",
    //    "architecture" : "x86_64",
    //    "modelName" : "Apple TV",
    //    "name" : "Apple TV"
    //  },
    //  {
    //    "simulator" : false,
    //    "operatingSystemVersion" : "13.3 (17C54)",
    //    "interface" : "usb",
    //    "available" : true,
    //    "platform" : "com.apple.platform.iphoneos",
    //    "modelCode" : "iPhone8,1",
    //    "identifier" : "d83d5bc53967baa0ee18626ba87b6254b2ab5418",
    //    "architecture" : "arm64",
    //    "modelName" : "iPhone 6s",
    //    "name" : "iPhone"
    //  },
    //  {
    //    "simulator" : true,
    //    "operatingSystemVersion" : "6.1.1 (17S445)",
    //    "available" : true,
    //    "platform" : "com.apple.platform.watchsimulator",
    //    "modelCode" : "Watch5,4",
    //    "identifier" : "2D74FB11-88A0-44D0-B81E-C0C142B1C94A",
    //    "architecture" : "i386",
    //    "modelName" : "Apple Watch Series 5 - 44mm",
    //    "name" : "Apple Watch Series 5 - 44mm"
    //  },
    // ...

    final Map<String, IOSDevice> deviceMap = <String, IOSDevice>{};
    for (final Object device in allAvailableDevices) {
      if (device is Map<String, Object?>) {
        // Only include iPhone, iPad, iPod, or other iOS devices.
        if (!_isIPhoneOSDevice(device)) {
          continue;
        }
        final String? identifier = device['identifier'] as String?;
        final String? name = device['name'] as String?;
        if (identifier == null || name == null) {
          continue;
        }
        bool devModeEnabled = true;
        bool isConnected = true;
        bool isPaired = true;
        final Map<String, Object?>? errorProperties = _errorProperties(device);
        if (errorProperties != null) {
          final String? errorMessage = _parseErrorMessage(errorProperties);
          if (errorMessage != null) {
            if (errorMessage.contains('not paired')) {
              UsageEvent('device', 'ios-trust-failure', flutterUsage: globals.flutterUsage).send();
              _analytics.send(Event.appleUsageEvent(workflow: 'device', parameter: 'ios-trust-failure'));

            }
            _logger.printTrace(errorMessage);
          }

          final int? code = _errorCode(errorProperties);

          // Temporary error -10: iPhone is busy: Preparing debugger support for iPhone.
          // Sometimes the app launch will fail on these devices until Xcode is done setting up the device.
          // Other times this is a false positive and the app will successfully launch despite the error.
          if (code != -10) {
            isConnected = false;
          }
          // Error: iPhone is not paired with your computer. To use iPhone with Xcode, unlock it and choose to trust this computer when prompted. (code -9)
          if (code == -9) {
            isPaired = false;
          }

          if (code == 6) {
            devModeEnabled = false;
          }
        }

        String? sdkVersionString = _sdkVersion(device);

        if (sdkVersionString != null) {
          final String? buildVersion = _buildVersion(device);
          if (buildVersion != null) {
            sdkVersionString = '$sdkVersionString $buildVersion';
          }
        }

        // Duplicate entries started appearing in Xcode 15, possibly due to
        // Xcode's new device connectivity stack.
        // If a duplicate entry is found in `xcdevice list`, don't overwrite
        // existing entry when the existing entry indicates the device is
        // connected and the current entry indicates the device is not connected.
        // Don't overwrite if current entry's sdkVersion is null.
        // Don't overwrite if both entries indicate the device is not
        // connected and the existing entry has a higher sdkVersion.
        if (deviceMap.containsKey(identifier)) {
          final IOSDevice deviceInMap = deviceMap[identifier]!;
          if ((deviceInMap.isConnected && !isConnected) || sdkVersionString == null) {
            continue;
          }

          final Version? sdkVersion = Version.parse(sdkVersionString);
          if (!deviceInMap.isConnected &&
              !isConnected &&
              sdkVersion != null &&
              deviceInMap.sdkVersion != null &&
              deviceInMap.sdkVersion!.compareTo(sdkVersion) > 0) {
            continue;
          }
        }

        DeviceConnectionInterface connectionInterface = _interfaceType(device);

        // CoreDevices (devices with iOS 17 and greater) no longer reflect the
        // correct connection interface or developer mode status in `xcdevice`.
        // Use `devicectl` to get that information for CoreDevices.
        final IOSCoreDevice? coreDevice = coreDeviceMap[identifier];
        if (coreDevice != null) {
          if (coreDevice.connectionInterface != null) {
            connectionInterface = coreDevice.connectionInterface!;
          }

          if (coreDevice.deviceProperties?.developerModeStatus != 'enabled') {
            devModeEnabled = false;
          }
        }

        deviceMap[identifier] = IOSDevice(
          identifier,
          name: name,
          cpuArchitecture: _cpuArchitecture(device),
          connectionInterface: connectionInterface,
          isConnected: isConnected,
          sdkVersion: sdkVersionString,
          iProxy: _iProxy,
          fileSystem: globals.fs,
          logger: _logger,
          iosDeploy: _iosDeploy,
          iMobileDevice: _iMobileDevice,
          coreDeviceControl: _coreDeviceControl,
          xcodeDebug: _xcodeDebug,
          platform: globals.platform,
          devModeEnabled: devModeEnabled,
          isPaired: isPaired,
          isCoreDevice: coreDevice != null,
        );
      }
    }
    return deviceMap.values.toList();
  }

  /// Despite the name, com.apple.platform.iphoneos includes iPhone, iPads, and all iOS devices.
  /// Excludes simulators.
  static bool _isIPhoneOSDevice(Map<String, Object?> deviceProperties) {
    final Object? platform = deviceProperties['platform'];
    if (platform is String) {
      return platform == 'com.apple.platform.iphoneos';
    }
    return false;
  }

  static Map<String, Object?>? _errorProperties(Map<String, Object?> deviceProperties) {
    final Object? error = deviceProperties['error'];
    return error is Map<String, Object?> ? error : null;
  }

  static int? _errorCode(Map<String, Object?>? errorProperties) {
    if (errorProperties == null) {
      return null;
    }
    final Object? code = errorProperties['code'];
    return code is int ? code : null;
  }

  static DeviceConnectionInterface _interfaceType(Map<String, Object?> deviceProperties) {
    // Interface can be "usb" or "network". It can also be missing
    // (e.g. simulators do not have an interface property).
    // If the interface is "network", use `DeviceConnectionInterface.wireless`,
    // otherwise use `DeviceConnectionInterface.attached.
    final Object? interface = deviceProperties['interface'];
    if (interface is String && interface.toLowerCase() == 'network') {
      return DeviceConnectionInterface.wireless;
    }
    return DeviceConnectionInterface.attached;
  }

  static String? _sdkVersion(Map<String, Object?> deviceProperties) {
    final Object? operatingSystemVersion = deviceProperties['operatingSystemVersion'];
    if (operatingSystemVersion is String) {
      // Parse out the OS version, ignore the build number in parentheses.
      // "13.3 (17C54)"
      final RegExp operatingSystemRegex = RegExp(r'(.*) \(.*\)$');
      if (operatingSystemRegex.hasMatch(operatingSystemVersion.trim())) {
        return operatingSystemRegex.firstMatch(operatingSystemVersion.trim())?.group(1);
      }
      return operatingSystemVersion;
    }
    return null;
  }

  static String? _buildVersion(Map<String, Object?> deviceProperties) {
    final Object? operatingSystemVersion = deviceProperties['operatingSystemVersion'];
    if (operatingSystemVersion is String) {
      // Parse out the build version, for example 17C54 from "13.3 (17C54)".
      final RegExp buildVersionRegex = RegExp(r'\(.*\)$');
      return buildVersionRegex.firstMatch(operatingSystemVersion)?.group(0)?.replaceAll(RegExp('[()]'), '');
    }
    return null;
  }

  DarwinArch _cpuArchitecture(Map<String, Object?> deviceProperties) {
    DarwinArch? cpuArchitecture;
    final Object? architecture = deviceProperties['architecture'];
    if (architecture is String) {
      try {
        cpuArchitecture = getIOSArchForName(architecture);
      } on Exception {
        // Fallback to default iOS architecture. Future-proof against a
        // theoretical version of Xcode that changes this string to something
        // slightly different like "ARM64", or armv7 variations like
        // armv7s and armv7f.
        if (architecture.startsWith('armv7')) {
          cpuArchitecture = DarwinArch.armv7;
        } else {
          cpuArchitecture = DarwinArch.arm64;
        }
        _logger.printWarning(
          'Unknown architecture $architecture, defaulting to '
          '${cpuArchitecture.name}',
        );
      }
    }
    return cpuArchitecture ?? DarwinArch.arm64;
  }

  /// Error message parsed from xcdevice. null if no error.
  static String? _parseErrorMessage(Map<String, Object?>? errorProperties) {
    //  {
    //    "simulator" : false,
    //    "operatingSystemVersion" : "13.3 (17C54)",
    //    "interface" : "usb",
    //    "available" : false,
    //    "platform" : "com.apple.platform.iphoneos",
    //    "modelCode" : "iPhone8,1",
    //    "identifier" : "98206e7a4afd4aedaff06e687594e089dede3c44",
    //    "architecture" : "arm64",
    //    "modelName" : "iPhone 6s",
    //    "name" : "iPhone",
    //    "error" : {
    //      "code" : -9,
    //      "failureReason" : "",
    //      "underlyingErrors" : [
    //        {
    //          "code" : 5,
    //          "failureReason" : "allowsSecureServices: 1. isConnected: 0. Platform: <DVTPlatform:0x7f804ce32880:'com.apple.platform.iphoneos':<DVTFilePath:0x7f804ce32800:'\/Users\/magder\/Applications\/Xcode_11-3-1.app\/Contents\/Developer\/Platforms\/iPhoneOS.platform'>>. DTDKDeviceIdentifierIsIDID: 0",
    //          "description" : "📱<DVTiOSDevice (0x7f801f190450), iPhone, iPhone, 13.3 (17C54), d83d5bc53967baa0ee18626ba87b6254b2ab5418> -- Failed _shouldMakeReadyForDevelopment check even though device is not locked by passcode.",
    //          "recoverySuggestion" : "",
    //          "domain" : "com.apple.platform.iphoneos"
    //        }
    //      ],
    //      "description" : "iPhone is not paired with your computer.",
    //      "recoverySuggestion" : "To use iPhone with Xcode, unlock it and choose to trust this computer when prompted.",
    //      "domain" : "com.apple.platform.iphoneos"
    //    }
    //  },
    //  {
    //    "simulator" : false,
    //    "operatingSystemVersion" : "13.3 (17C54)",
    //    "interface" : "usb",
    //    "available" : false,
    //    "platform" : "com.apple.platform.iphoneos",
    //    "modelCode" : "iPhone8,1",
    //    "identifier" : "d83d5bc53967baa0ee18626ba87b6254b2ab5418",
    //    "architecture" : "arm64",
    //    "modelName" : "iPhone 6s",
    //    "name" : "iPhone",
    //    "error" : {
    //      "code" : -9,
    //      "failureReason" : "",
    //      "description" : "iPhone is not paired with your computer.",
    //      "domain" : "com.apple.platform.iphoneos"
    //    }
    //  }
    // ...

    if (errorProperties == null) {
      return null;
    }

    final StringBuffer errorMessage = StringBuffer('Error: ');

    final Object? description = errorProperties['description'];
    if (description is String) {
      errorMessage.write(description);
      if (!description.endsWith('.')) {
        errorMessage.write('.');
      }
    } else {
      errorMessage.write('Xcode pairing error.');
    }

    final Object? recoverySuggestion = errorProperties['recoverySuggestion'];
    if (recoverySuggestion is String) {
      errorMessage.write(' $recoverySuggestion');
    }

    final int? code = _errorCode(errorProperties);
    if (code != null) {
      errorMessage.write(' (code $code)');
    }

    return errorMessage.toString();
  }

  /// List of all devices reporting errors.
  Future<List<String>> getDiagnostics() async {
    final List<Object>? allAvailableDevices = await _getAllDevices(
      useCache: true,
      timeout: const Duration(seconds: 2)
    );

    if (allAvailableDevices == null) {
      return const <String>[];
    }

    final List<String> diagnostics = <String>[];
    for (final Object deviceProperties in allAvailableDevices) {
      if (deviceProperties is! Map<String, Object?>) {
        continue;
      }
      final Map<String, Object?>? errorProperties = _errorProperties(deviceProperties);
      final String? errorMessage = _parseErrorMessage(errorProperties);
      if (errorMessage != null) {
        final int? code = _errorCode(errorProperties);
        // Error -13: iPhone is not connected. Xcode will continue when iPhone is connected.
        // This error is confusing since the device is not connected and maybe has not been connected
        // for a long time. Avoid showing it.
        if (code == -13 && errorMessage.contains('not connected')) {
          continue;
        }

        diagnostics.add(errorMessage);
      }
    }
    return diagnostics;
  }
}
