// 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.

// @dart = 2.8

import 'dart:async';

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

import '../artifacts.dart';
import '../base/common.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../globals_null_migrated.dart' as globals;
import '../ios/devices.dart';
import '../ios/ios_deploy.dart';
import '../ios/iproxy.dart';
import '../ios/mac.dart';
import '../reporting/reporting.dart';
import 'xcode.dart';

enum XCDeviceEvent {
  attach,
  detach,
}

/// 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,
  }) : _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,
      ),
      _iProxy = iproxy,
      _xcode = xcode {

    _setupDeviceIdentifierByEventStream();
  }

  void dispose() {
    _deviceObservationProcess?.kill();
  }

  final ProcessUtils _processUtils;
  final Logger _logger;
  final IMobileDevice _iMobileDevice;
  final IOSDeploy _iosDeploy;
  final Xcode _xcode;
  final IProxy _iProxy;

  List<dynamic> _cachedListResults;
  Process _deviceObservationProcess;
  StreamController<Map<XCDeviceEvent, String>> _deviceIdentifierByEvent;

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

  bool get isInstalled => _xcode.isInstalledAndMeetsVersionCheck;

  Future<List<dynamic>> _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 List<dynamic> listResults = json.decode(result.stdout) as List<dynamic>;
        _cachedListResults = listResults;
        return listResults;
      }
      _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 is a tuple of one event type
  /// and identifier.
  Stream<Map<XCDeviceEvent, String>> observedDeviceEvents() {
    if (!isInstalled) {
      _logger.printTrace("Xcode not found. Run 'flutter doctor' for more information.");
      return null;
    }
    return _deviceIdentifierByEvent.stream;
  }

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

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

      // Run in interactive mode (via script) to convince
      // xcdevice it has a terminal attached in order to redirect stdout.
      _deviceObservationProcess = await _processUtils.start(
        <String>[
          'script',
          '-t',
          '0',
          '/dev/null',
          ..._xcode.xcrunCommand(),
          'xcdevice',
          'observe',
          '--both',
        ],
      );

      final StreamSubscription<String> stdoutSubscription = _deviceObservationProcess.stdout
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {

        // 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')) {
            _deviceIdentifierByEvent.add(<XCDeviceEvent, String>{
              XCDeviceEvent.attach: identifier
            });
          } else if (verb.startsWith('detach')) {
            _deviceIdentifierByEvent.add(<XCDeviceEvent, String>{
              XCDeviceEvent.detach: identifier
            });
          }
        }
      });
      final StreamSubscription<String> stderrSubscription = _deviceObservationProcess.stderr
        .transform<String>(utf8.decoder)
        .transform<String>(const LineSplitter())
        .listen((String line) {
        _logger.printTrace('xcdevice observe error: $line');
      });
      unawaited(_deviceObservationProcess.exitCode.then((int status) {
        _logger.printTrace('xcdevice exited with code $exitCode');
        unawaited(stdoutSubscription.cancel());
        unawaited(stderrSubscription.cancel());
      }).whenComplete(() async {
        if (_deviceIdentifierByEvent.hasListener) {
          // Tell listeners the process died.
          await _deviceIdentifierByEvent.close();
        }
        _deviceObservationProcess = null;

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

  void _stopObservingTetheredIOSDevices() {
    _deviceObservationProcess?.kill();
  }

  /// [timeout] defaults to 2 seconds.
  Future<List<IOSDevice>> getAvailableIOSDevices({ Duration timeout }) async {
    final List<dynamic> allAvailableDevices = await _getAllDevices(timeout: timeout ?? const Duration(seconds: 2));

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

    // [
    //  {
    //    "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 List<IOSDevice> devices = <IOSDevice>[];
    for (final dynamic device in allAvailableDevices) {
      if (device is Map<String, dynamic>) {
        // Only include iPhone, iPad, iPod, or other iOS devices.
        if (!_isIPhoneOSDevice(device)) {
          continue;
        }

        final Map<String, dynamic> errorProperties = _errorProperties(device);
        if (errorProperties != null) {
          final String errorMessage = _parseErrorMessage(errorProperties);
          if (errorMessage.contains('not paired')) {
            UsageEvent('device', 'ios-trust-failure', flutterUsage: globals.flutterUsage).send();
          }
          _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) {
            continue;
          }
        }

        final IOSDeviceInterface interface = _interfaceType(device);

        // Only support USB devices, skip "network" interface (Xcode > Window > Devices and Simulators > Connect via network).
        // TODO(jmagman): Remove this check once wirelessly detected devices can be observed and attached, https://github.com/flutter/flutter/issues/15072.
        if (interface != IOSDeviceInterface.usb) {
          continue;
        }

        String sdkVersion = _sdkVersion(device);

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

        devices.add(IOSDevice(
          device['identifier'] as String,
          name: device['name'] as String,
          cpuArchitecture: _cpuArchitecture(device),
          interfaceType: interface,
          sdkVersion: sdkVersion,
          iProxy: _iProxy,
          fileSystem: globals.fs,
          logger: _logger,
          iosDeploy: _iosDeploy,
          iMobileDevice: _iMobileDevice,
          platform: globals.platform,
        ));
      }
    }
    return devices;

  }

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

  static Map<String, dynamic> _errorProperties(Map<String, dynamic> deviceProperties) {
    if (deviceProperties.containsKey('error')) {
      return deviceProperties['error'] as Map<String, dynamic>;
    }
    return null;
  }

  static int _errorCode(Map<String, dynamic> errorProperties) {
    if (errorProperties.containsKey('code') && errorProperties['code'] is int) {
      return errorProperties['code'] as int;
    }
    return null;
  }

  static IOSDeviceInterface _interfaceType(Map<String, dynamic> deviceProperties) {
    // Interface can be "usb", "network", or "none" for simulators
    // and unknown future interfaces.
    if (deviceProperties.containsKey('interface')) {
      if ((deviceProperties['interface'] as String).toLowerCase() == 'network') {
        return IOSDeviceInterface.network;
      } else {
        return IOSDeviceInterface.usb;
      }
    }

    return IOSDeviceInterface.none;
  }

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

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

  DarwinArch _cpuArchitecture(Map<String, dynamic> deviceProperties) {
    DarwinArch cpuArchitecture;
    if (deviceProperties.containsKey('architecture')) {
      final String architecture = deviceProperties['architecture'] as 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.printError(
          'Unknown architecture $architecture, defaulting to '
          '${getNameForDarwinArch(cpuArchitecture)}',
        );
      }
    }
    return cpuArchitecture;
  }

  /// Error message parsed from xcdevice. null if no error.
  static String _parseErrorMessage(Map<String, dynamic> 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: ');

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

    if (errorProperties.containsKey('recoverySuggestion')) {
      final String recoverySuggestion = errorProperties['recoverySuggestion'] as 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<dynamic> allAvailableDevices = await _getAllDevices(
      useCache: true,
      timeout: const Duration(seconds: 2)
    );

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

    final List<String> diagnostics = <String>[];
    for (final dynamic device in allAvailableDevices) {
      if (device is! Map) {
        continue;
      }
      final Map<String, dynamic> deviceProperties = device as Map<String, dynamic>;
      final Map<String, dynamic> errorProperties = _errorProperties(deviceProperties);
      final String errorMessage = _parseErrorMessage(errorProperties);
      if (errorMessage != null) {
        diagnostics.add(errorMessage);
      }
    }
    return diagnostics;
  }
}
