// 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 'package:meta/meta.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart' as vm_service_io;

import '../base/io.dart';
import '../base/logger.dart';
import '../device.dart';
import '../mdns_discovery.dart';
import '../protocol_discovery.dart';
import '../reporting/reporting.dart';

typedef VmServiceConnector = Future<VmService> Function(String, {Log log});

/// A protocol for discovery of a vmservice on an attached iOS device with
/// multiple fallbacks.
///
/// On versions of iOS 13 and greater, libimobiledevice can no longer listen to
/// logs directly. The only way to discover an active observatory is through the
/// mDNS protocol. However, there are a number of circumstances where this breaks
/// down, such as when the device is connected to certain wifi networks or with
/// certain hotspot connections enabled.
///
/// Another approach to discover a vmservice is to attempt to assign a
/// specific port and then attempt to connect. This may fail if the port is
/// not available. This port value should be either random, or otherwise
/// generated with application specific input. This reduces the chance of
/// accidentally connecting to another running flutter application.
///
/// Finally, if neither of the above approaches works, we can still attempt
/// to parse logs.
///
/// To improve the overall resilience of the process, this class combines the
/// three discovery strategies. First it assigns a port and attempts to connect.
/// Then if this fails it falls back to mDNS, then finally attempting to scan
/// logs.
class FallbackDiscovery {
  FallbackDiscovery({
    @required DevicePortForwarder portForwarder,
    @required MDnsObservatoryDiscovery mDnsObservatoryDiscovery,
    @required Logger logger,
    @required ProtocolDiscovery protocolDiscovery,
    @required Usage flutterUsage,
    VmServiceConnector vmServiceConnectUri =
      vm_service_io.vmServiceConnectUri,
    Duration pollingDelay = const Duration(seconds: 2),
  }) : _logger = logger,
       _mDnsObservatoryDiscovery = mDnsObservatoryDiscovery,
       _portForwarder = portForwarder,
       _protocolDiscovery = protocolDiscovery,
       _flutterUsage = flutterUsage,
       _vmServiceConnectUri = vmServiceConnectUri,
       _pollingDelay = pollingDelay;

  static const String _kEventName = 'ios-handshake';

  final DevicePortForwarder _portForwarder;
  final MDnsObservatoryDiscovery _mDnsObservatoryDiscovery;
  final Logger _logger;
  final ProtocolDiscovery _protocolDiscovery;
  final Usage _flutterUsage;
  final VmServiceConnector  _vmServiceConnectUri;
  final Duration _pollingDelay;

  /// Attempt to discover the observatory port.
  Future<Uri> discover({
    @required int assumedDevicePort,
    @required String packageId,
    @required Device deivce,
    @required bool usesIpv6,
    @required int hostVmservicePort,
    @required String packageName,
  }) async {
    final Uri result = await _attemptServiceConnection(
      assumedDevicePort: assumedDevicePort,
      hostVmservicePort: hostVmservicePort,
      packageName: packageName,
    );
    if (result != null) {
      return result;
    }

    try {
      final Uri result = await _mDnsObservatoryDiscovery.getObservatoryUri(
        packageId,
        deivce,
        usesIpv6: usesIpv6,
        hostVmservicePort: hostVmservicePort,
      );
      if (result != null) {
        UsageEvent(
          _kEventName,
          'mdns-success',
          flutterUsage: _flutterUsage,
        ).send();
        return result;
      }
    } on Exception catch (err) {
      _logger.printTrace(err.toString());
    }
    _logger.printTrace('Failed to connect with mDNS, falling back to log scanning');
    UsageEvent(
      _kEventName,
      'mdns-failure',
      flutterUsage: _flutterUsage,
    ).send();

    try {
      final Uri result = await _protocolDiscovery.uri;
      if (result != null) {
        UsageEvent(
          _kEventName,
          'fallback-success',
          flutterUsage: _flutterUsage,
        ).send();
        return result;
      }
    } on ArgumentError {
    // In the event of an invalid InternetAddress, this code attempts to catch
    // an ArgumentError from protocol_discovery.dart
    } on Exception catch (err) {
      _logger.printTrace(err.toString());
    }
    _logger.printTrace('Failed to connect with log scanning');
    UsageEvent(
      _kEventName,
      'fallback-failure',
      flutterUsage: _flutterUsage,
    ).send();
    return null;
  }

  // Attempt to connect to the VM service and find an isolate with a matching `packageName`.
  // Returns `null` if no connection can be made.
  Future<Uri> _attemptServiceConnection({
    @required int assumedDevicePort,
    @required int  hostVmservicePort,
    @required String packageName,
  }) async {
    int hostPort;
    Uri assumedWsUri;
    try {
      hostPort = await _portForwarder.forward(
        assumedDevicePort,
        hostPort: hostVmservicePort,
      );
      assumedWsUri = Uri.parse('ws://localhost:$hostPort/ws');
    } on Exception catch (err) {
      _logger.printTrace(err.toString());
      _logger.printTrace('Failed to connect directly, falling back to mDNS');
      _sendFailureEvent(err, assumedDevicePort);
      return null;
    }

    // Attempt to connect to the VM service 5 times.
    int attempts = 0;
    Exception firstException;
    while (attempts < 5) {
      try {
        final VmService vmService = await _vmServiceConnectUri(
          assumedWsUri.toString(),
        );
        final VM vm = await vmService.getVM();
        for (final IsolateRef isolateRefs in vm.isolates) {
          final Isolate isolateResponse = await vmService.getIsolate(
            isolateRefs.id,
          );
          final LibraryRef library = isolateResponse.rootLib;
          if (library != null && library.uri.startsWith('package:$packageName')) {
            UsageEvent(
              _kEventName,
              'success',
              flutterUsage: _flutterUsage,
            ).send();
            return Uri.parse('http://localhost:$hostPort');
          }
        }
      } on Exception catch (err) {
        // No action, we might have failed to connect.
        firstException ??= err;
        _logger.printTrace(err.toString());
      }

      // No exponential backoff is used here to keep the amount of time the
      // tool waits for a connection to be reasonable. If the vmservice cannot
      // be connected to in this way, the mDNS discovery must be reached
      // sooner rather than later.
      await Future<void>.delayed(_pollingDelay);
      attempts += 1;
    }
    _logger.printTrace('Failed to connect directly, falling back to mDNS');
    _sendFailureEvent(firstException, assumedDevicePort);
    return null;
  }

  void _sendFailureEvent(Exception err, int assumedDevicePort) {
    String eventAction;
    String eventLabel;
    if (err == null) {
      eventAction = 'failure-attempts-exhausted';
      eventLabel = assumedDevicePort.toString();
    } else if (err is HttpException) {
      eventAction = 'failure-http';
      eventLabel = '${err.message}, device port = $assumedDevicePort';
    } else {
      eventAction = 'failure-other';
      eventLabel = '$err, device port = $assumedDevicePort';
    }
    UsageEvent(
      _kEventName,
      eventAction,
      label: eventLabel,
      flutterUsage: _flutterUsage,
    ).send();
  }
}
