// 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 '../globals.dart' as globals;
import '../mdns_discovery.dart';
import '../protocol_discovery.dart';
import '../reporting/reporting.dart';

/// 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,
    Future<VmService> Function(String wsUri, {Log log}) vmServiceConnectUri = vm_service_io.vmServiceConnectUri,
  }) : _logger = logger,
       _mDnsObservatoryDiscovery = mDnsObservatoryDiscovery,
       _portForwarder = portForwarder,
       _protocolDiscovery = protocolDiscovery,
       _vmServiceConnectUri = vmServiceConnectUri;

  static const String _kEventName = 'ios-handshake';

  final DevicePortForwarder _portForwarder;
  final MDnsObservatoryDiscovery _mDnsObservatoryDiscovery;
  final Logger _logger;
  final ProtocolDiscovery _protocolDiscovery;
  final Future<VmService> Function(String wsUri, {Log log}) _vmServiceConnectUri;

  /// 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: globals.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: globals.flutterUsage).send();

    try {
      final Uri result = await _protocolDiscovery.uri;
      UsageEvent(_kEventName, 'fallback-success', flutterUsage: globals.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: globals.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;
    const int kDelaySeconds = 2;
    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 dynamic isolateResponse = await vmService.getIsolate(isolateRefs.id);
          if (isolateResponse is Sentinel) {
            // Might have been a Sentinel. Try again later.
            throw Exception('Expected Isolate but found Sentinel: $isolateResponse');
          }
          final LibraryRef library = (isolateResponse as Isolate).rootLib;
          if (library.uri.startsWith('package:$packageName')) {
            UsageEvent(_kEventName, 'success', flutterUsage: globals.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(const Duration(seconds: kDelaySeconds));
      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: globals.flutterUsage,
    ).send();
  }
}
