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

import 'package:meta/meta.dart';

import '../application_package.dart';
import '../base/dds.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../build_info.dart';
import '../convert.dart';
import '../daemon.dart';
import '../device.dart';
import '../device_port_forwarder.dart';
import '../device_vm_service_discovery_for_attach.dart';
import '../project.dart';
import 'debounce_data_stream.dart';
import 'file_transfer.dart';

bool _isNullable<T>() => null is T;

T _cast<T>(Object? object) {
  if (!_isNullable<T>() && object == null) {
    throw Exception('Expected $T, received null!');
  } else {
    return object as T;
  }
}

/// A [DeviceDiscovery] that will connect to a flutter daemon and connects to
/// the devices remotely.
///
/// If [deltaFileTransfer] is true, the proxy will use an rsync-like algorithm that
/// only transfers the changed part of the application package for deployment.
class ProxiedDevices extends PollingDeviceDiscovery {
  ProxiedDevices(this.connection, {
    bool deltaFileTransfer = true,
    bool enableDdsProxy = false,
    required Logger logger,
    FileTransfer fileTransfer = const FileTransfer(),
  }) : _deltaFileTransfer = deltaFileTransfer,
       _enableDdsProxy = enableDdsProxy,
       _logger = logger,
       _fileTransfer = fileTransfer,
       super('Proxied devices');

  /// [DaemonConnection] used to communicate with the daemon.
  final DaemonConnection connection;

  final Logger _logger;

  final bool _deltaFileTransfer;

  final bool _enableDdsProxy;

  final FileTransfer _fileTransfer;

  @override
  bool get supportsPlatform => true;

  @override
  bool get canListAnything => true;

  List<Device>? _devices;

  @override
  Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async =>
      _filterDevices(_devices ?? await discoverDevices(), filter);

  @override
  Future<List<Device>> discoverDevices({
    Duration? timeout,
    DeviceDiscoveryFilter? filter
  }) async {
    final List<Map<String, Object?>> discoveredDevices = _cast<List<dynamic>>(await connection.sendRequest('device.discoverDevices')).cast<Map<String, Object?>>();
    final List<ProxiedDevice> devices = <ProxiedDevice>[
      for (final Map<String, Object?> device in discoveredDevices)
        deviceFromDaemonResult(device),
    ];

    _devices = devices;
    return _filterDevices(devices, filter);
  }

  Future<List<Device>> _filterDevices(List<Device> devices, DeviceDiscoveryFilter? filter) async {
    if (filter == null) {
      return devices;
    }
    return filter.filterDevices(devices);
  }

  @override
  Future<List<Device>> pollingGetDevices({Duration? timeout}) => discoverDevices(timeout: timeout);

  @override
  List<String> get wellKnownIds => const <String>[];

  @visibleForTesting
  ProxiedDevice deviceFromDaemonResult(Map<String, Object?> device) {
    final Map<String, Object?> capabilities = _cast<Map<String, Object?>>(device['capabilities']);
    final String? connectionInterfaceName = _cast<String?>(device['connectionInterface']);
    final DeviceConnectionInterface? connectionInterface = connectionInterfaceName != null ? getDeviceConnectionInterfaceForName(connectionInterfaceName) : null;
    return ProxiedDevice(
      connection, _cast<String>(device['id']),
      deltaFileTransfer: _deltaFileTransfer,
      enableDdsProxy: _enableDdsProxy,
      category: Category.fromString(_cast<String>(device['category'])),
      platformType: PlatformType.fromString(_cast<String>(device['platformType'])),
      targetPlatform: getTargetPlatformForName(_cast<String>(device['platform'])),
      ephemeral: _cast<bool>(device['ephemeral']),
      isConnected: _cast<bool?>(device['isConnected']) ?? true,
      connectionInterface: connectionInterface ?? DeviceConnectionInterface.attached,
      name: 'Proxied ${device['name']}',
      isLocalEmulator: _cast<bool>(device['emulator']),
      emulatorId: _cast<String?>(device['emulatorId']),
      sdkNameAndVersion: _cast<String>(device['sdk']),
      supportsHotReload: _cast<bool>(capabilities['hotReload']),
      supportsHotRestart: _cast<bool>(capabilities['hotRestart']),
      supportsFlutterExit: _cast<bool>(capabilities['flutterExit']),
      supportsScreenshot: _cast<bool>(capabilities['screenshot']),
      supportsFastStart: _cast<bool>(capabilities['fastStart']),
      supportsHardwareRendering: _cast<bool>(capabilities['hardwareRendering']),
      logger: _logger,
      fileTransfer: _fileTransfer,
    );
  }

  @override
  Future<List<String>> getDiagnostics() async {
    try {
      final List<String> diagnostics = _cast<List<dynamic>>(await connection.sendRequest('device.getDiagnostics')).cast<String>();
      return diagnostics;
    } on String catch (e) { // Daemon actually does throw string types.
      if (e.contains('command not understood')) {
        _logger.printTrace('The daemon is on an older version that does not support `device.getDiagnostics`.');
        // Silently ignore.
        return <String>[];
      }
      rethrow;
    }
  }
}

/// A [Device] that acts as a proxy to remotely connected device.
///
/// The communication happens via a flutter daemon.
///
/// If [deltaFileTransfer] is true, the proxy will use an rsync-like algorithm that
/// only transfers the changed part of the application package for deployment.
///
/// If [enableDdsProxy] is true, DDS will be started on the daemon instead of
/// starting locally.
class ProxiedDevice extends Device {
  ProxiedDevice(this.connection, String id, {
    bool deltaFileTransfer = true,
    bool enableDdsProxy = false,
    required Category? category,
    required PlatformType? platformType,
    required TargetPlatform targetPlatform,
    required bool ephemeral,
    required this.isConnected,
    required this.connectionInterface,
    required this.name,
    required bool isLocalEmulator,
    required String? emulatorId,
    required String sdkNameAndVersion,
    required this.supportsHotReload,
    required this.supportsHotRestart,
    required this.supportsFlutterExit,
    required this.supportsScreenshot,
    required this.supportsFastStart,
    required bool supportsHardwareRendering,
    required Logger logger,
    FileTransfer fileTransfer = const FileTransfer(),
  }): _deltaFileTransfer = deltaFileTransfer,
      _enableDdsProxy = enableDdsProxy,
      _isLocalEmulator = isLocalEmulator,
      _emulatorId = emulatorId,
      _sdkNameAndVersion = sdkNameAndVersion,
      _supportsHardwareRendering = supportsHardwareRendering,
      _targetPlatform = targetPlatform,
      _logger = logger,
      _fileTransfer = fileTransfer,
      super(id,
        category: category,
        platformType: platformType,
        ephemeral: ephemeral);

  /// [DaemonConnection] used to communicate with the daemon.
  final DaemonConnection connection;

  final Logger _logger;

  final bool _deltaFileTransfer;

  final bool _enableDdsProxy;

  final FileTransfer _fileTransfer;

  @override
  final bool isConnected;

  @override
  final DeviceConnectionInterface connectionInterface;

  @override
  final String name;

  final bool _isLocalEmulator;
  @override
  Future<bool> get isLocalEmulator async => _isLocalEmulator;

  final String? _emulatorId;
  @override
  Future<String?> get emulatorId async => _emulatorId;

  @override
  Future<bool> supportsRuntimeMode(BuildMode buildMode) async =>
     _cast<bool>(await connection.sendRequest('device.supportsRuntimeMode', <String, Object>{
      'deviceId': id,
      'buildMode': buildMode.toString(),
    }));

  final bool _supportsHardwareRendering;
  @override
  Future<bool> get supportsHardwareRendering async => _supportsHardwareRendering;

  // ProxiedDevice is intended to be used with prebuilt projects. No building
  // is required, so we returns true for all projects.
  @override
  bool isSupportedForProject(FlutterProject flutterProject) => true;

  @override
  Future<bool> isAppInstalled(
    ApplicationPackage app, {
    String? userIdentifier,
  }) => throw UnimplementedError();

  @override
  Future<bool> isLatestBuildInstalled(ApplicationPackage app) => throw UnimplementedError();

  @override
  Future<bool> installApp(
    ApplicationPackage app, {
    String? userIdentifier,
  }) => throw UnimplementedError();

  @override
  Future<bool> uninstallApp(
    ApplicationPackage app, {
    String? userIdentifier,
  }) => throw UnimplementedError();

  @override
  bool isSupported() => true;

  final TargetPlatform _targetPlatform;
  @override
  Future<TargetPlatform> get targetPlatform async => _targetPlatform;
  TargetPlatform get targetPlatformSync => _targetPlatform;

  final String _sdkNameAndVersion;
  @override
  Future<String> get sdkNameAndVersion async => _sdkNameAndVersion;

  @override
  FutureOr<DeviceLogReader> getLogReader({
    covariant PrebuiltApplicationPackage? app,
    bool includePastLogs = false,
  }) => _ProxiedLogReader(connection, this, app);

  ProxiedPortForwarder? _proxiedPortForwarder;
  /// [proxiedPortForwarder] forwards a port from the remote host to local host.
  ProxiedPortForwarder get proxiedPortForwarder => _proxiedPortForwarder ??= ProxiedPortForwarder(connection, logger: _logger);

  ProxiedPortForwarder? _portForwarder;
  /// [portForwarder] forwards a port from the remote device to remote host, and
  /// then forward the port from remote host to local host.
  @override
  ProxiedPortForwarder get portForwarder => _portForwarder ??= ProxiedPortForwarder(connection, deviceId: id, logger: _logger);

  ProxiedDartDevelopmentService? _proxiedDds;
  @override
  DartDevelopmentService get dds {
    if (!_enableDdsProxy) {
      return super.dds;
    }
    return _proxiedDds ??= ProxiedDartDevelopmentService(connection, id,
        logger: _logger, proxiedPortForwarder: proxiedPortForwarder, devicePortForwarder: portForwarder);
  }

  @override
  void clearLogs() => throw UnimplementedError();

  @override
  VMServiceDiscoveryForAttach getVMServiceDiscoveryForAttach({
    String? appId,
    String? fuchsiaModule,
    int? filterDevicePort,
    int? expectedHostPort,
    required bool ipv6,
    required Logger logger,
  }) =>
      ProxiedVMServiceDiscoveryForAttach(
        connection,
        id,
        proxiedPortForwarder: proxiedPortForwarder,
        appId: appId,
        fuchsiaModule: fuchsiaModule,
        filterDevicePort: filterDevicePort,
        expectedHostPort: expectedHostPort,
        ipv6: ipv6,
        logger: logger,
        fallbackDiscovery: () => super.getVMServiceDiscoveryForAttach(
          appId: appId,
          fuchsiaModule: fuchsiaModule,
          filterDevicePort: filterDevicePort,
          expectedHostPort: expectedHostPort,
          ipv6: ipv6,
          logger: logger,
        ),
      );

  @override
  Future<LaunchResult> startApp(
    PrebuiltApplicationPackage package, {
    String? mainPath,
    String? route,
    required DebuggingOptions debuggingOptions,
    Map<String, Object?> platformArgs = const <String, Object?>{},
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String? userIdentifier,
  }) async {
    final Map<String, Object?> result = _cast<Map<String, Object?>>(await connection.sendRequest('device.startApp', <String, Object?>{
      'deviceId': id,
      'applicationPackageId': await applicationPackageId(package),
      'mainPath': mainPath,
      'route': route,
      'debuggingOptions': debuggingOptions.toJson(),
      'platformArgs': platformArgs,
      'prebuiltApplication': prebuiltApplication,
      'ipv6': ipv6,
      'userIdentifier': userIdentifier,
    }));
    final bool started = _cast<bool>(result['started']);
    // TODO(bkonyi): remove once clients have migrated to relying on vmServiceUri.
    final String? vmServiceUriStr = _cast<String?>(result['vmServiceUri']) ?? _cast<String?>(result['observatoryUri']);
    final Uri? vmServiceUri = vmServiceUriStr == null ? null : Uri.parse(vmServiceUriStr);
    if (started) {
      if (vmServiceUri != null) {
        final int hostPort = await proxiedPortForwarder.forward(vmServiceUri.port);
        return LaunchResult.succeeded(vmServiceUri: vmServiceUri.replace(port: hostPort));
      } else {
        return LaunchResult.succeeded();
      }
    } else {
      return LaunchResult.failed();
    }
  }

  @override
  final bool supportsHotReload;

  @override
  final bool supportsHotRestart;

  @override
  final bool supportsFlutterExit;

  @override
  final bool supportsScreenshot;

  @override
  final bool supportsFastStart;

  @override
  Future<bool> stopApp(
    covariant PrebuiltApplicationPackage? app, {
    String? userIdentifier,
  }) async {
    return _cast<bool>(await connection.sendRequest('device.stopApp', <String, Object?>{
      'deviceId': id,
      if (app != null)
        'applicationPackageId': await applicationPackageId(app),
      'userIdentifier': userIdentifier,
    }));
  }

  @override
  Future<MemoryInfo> queryMemoryInfo() => throw UnimplementedError();

  @override
  Future<void> takeScreenshot(File outputFile) async {
    final String imageBase64 = _cast<String>(await connection.sendRequest('device.takeScreenshot', <String, Object?>{
      'deviceId': id,
    }));
    await outputFile.writeAsBytes(base64.decode(imageBase64));
  }

  @override
  Future<void> dispose() async {
    await proxiedPortForwarder.dispose();
  }

  final Map<String, Future<String>> _applicationPackageMap =
      <String, Future<String>>{};
  Future<String> applicationPackageId(
      PrebuiltApplicationPackage package) async {
    final File binary = package.applicationPackage as File;
    final String path = binary.absolute.path;
    if (_applicationPackageMap.containsKey(path)) {
      return _applicationPackageMap[path]!;
    }
    final String fileName = binary.basename;
    final Completer<String> idCompleter = Completer<String>();
    _applicationPackageMap[path] = idCompleter.future;

    final Map<String, Object> args = <String, Object>{'path': fileName};

    Map<String, Object?>? rollingHashResultJson;
    if (_deltaFileTransfer) {
      rollingHashResultJson = _cast<Map<String, Object?>?>(await connection.sendRequest('proxy.calculateFileHashes', args));
    }

    if (rollingHashResultJson == null) {
      // Either file not found on the remote end, or deltaFileTransfer is set to false, transfer the file directly.
      if (_deltaFileTransfer) {
        _logger.printTrace('Delta file transfer is enabled but file is not found on the remote end, do a full transfer.');
      }

      await connection.sendRequest('proxy.writeTempFile', args, await binary.readAsBytes());
    } else {
      final BlockHashes rollingHashResult = BlockHashes.fromJson(rollingHashResultJson);
      final List<FileDeltaBlock> delta = await _fileTransfer.computeDelta(binary, rollingHashResult);

      // Delta is empty if the file does not need to be updated
      if (delta.isNotEmpty) {
        final List<Map<String, Object>> deltaJson = delta.map((FileDeltaBlock block) => block.toJson()).toList();
        final Uint8List buffer = await _fileTransfer.binaryForRebuilding(binary, delta);

        await connection.sendRequest('proxy.updateFile', <String, Object>{
          'path': fileName,
          'delta': deltaJson,
        }, buffer);
      }
    }

    if (_deltaFileTransfer) {
      // Ask the daemon to precache the hash content for subsequent runs.
      // Wait for several seconds for the app to be launched, to not interfere
      // with whatever the daemon is doing.
      unawaited(() async {
        await Future<void>.delayed(const Duration(seconds: 60));
        await connection.sendRequest('proxy.calculateFileHashes', <String, Object>{
          'path': fileName,
          'cacheResult': true,
        });
      }());
    }

    final String id = _cast<String>(await connection.sendRequest('device.uploadApplicationPackage', <String, Object>{
      'targetPlatform': getNameForTargetPlatform(_targetPlatform),
      'applicationBinary': fileName,
    }));
    idCompleter.complete(id);
    return id;
  }
}

/// A [DeviceLogReader] for a proxied device.
class _ProxiedLogReader extends DeviceLogReader {
  _ProxiedLogReader(this.connection, this.device, this.applicationPackage);

  final DaemonConnection connection;
  final ProxiedDevice device;
  final PrebuiltApplicationPackage? applicationPackage;

  @override
  String get name => device.name;

  final StreamController<String> _logLinesStreamController = StreamController<String>();
  Stream<String>? _logLines;

  String? _id;

  @override
  Stream<String> get logLines => _logLines ??= _start();

  Stream<String> _start() {
    final PrebuiltApplicationPackage? package = applicationPackage;
    final Future<String?> applicationPackageId = package != null ? device.applicationPackageId(package) : Future<String?>.value();
    final Future<String> idFuture = applicationPackageId.then((String? applicationPackageId) async =>
       _cast<String>(await connection.sendRequest('device.logReader.start', <String, Object>{
        'deviceId': device.id,
        if (applicationPackageId != null)
          'applicationPackageId': applicationPackageId,
      })));
    idFuture.then((String id) {
      _id = id;
      final Stream<String> stream = connection.listenToEvent('device.logReader.logLines.$_id').map((DaemonEventData event) => event.data! as String);
      _logLinesStreamController.addStream(stream);
    });
    return _logLinesStreamController.stream;
  }

  @override
  void dispose() {
    if (_id != null) {
      connection.sendRequest('device.logReader.stop', <String, Object?>{
        'id': _id,
      });
    }
  }
}

/// A port forwarded by a [ProxiedPortForwarder].
class _ProxiedForwardedPort extends ForwardedPort {
  _ProxiedForwardedPort(this.connection, {
    required int hostPort,
    required int devicePort,
    required this.remoteDevicePort,
    required this.deviceId,
    required this.serverSocket
  }): super(hostPort, devicePort);

  /// [DaemonConnection] used to communicate with the daemon.
  final DaemonConnection connection;

  /// The forwarded port on the remote device.
  final int? remoteDevicePort;

  /// The device identifier of the remote device.
  final String? deviceId;

  /// The [ServerSocket] that is serving the local forwarded port.
  final ServerSocket serverSocket;

  @override
  void dispose() {
    unforward();
  }

  /// Unforwards the remote port, and stops the local server.
  Future<void> unforward() async {
    await serverSocket.close();

    if (remoteDevicePort != null && deviceId != null) {
      await connection.sendRequest('device.unforward', <String, Object>{
        'deviceId': deviceId!,
        'devicePort': remoteDevicePort!,
        'hostPort': devicePort,
      });
    }
  }
}

typedef CreateSocketServer = Future<ServerSocket> Function(Logger logger, int? hostPort, bool? ipv6);

/// A [DevicePortForwarder] for a proxied device.
///
/// If [deviceId] is not null, the port forwarder forwards ports from the remote
/// device, to the remote host, and then to the local host.
///
/// If [deviceId] is null, then the port forwarder only forwards ports from the
/// remote host to the local host.
@visibleForTesting
class ProxiedPortForwarder extends DevicePortForwarder {
  ProxiedPortForwarder(this.connection, {
    String? deviceId,
    required Logger logger,
    @visibleForTesting CreateSocketServer createSocketServer = _defaultCreateServerSocket,
  }) : _logger = logger,
       _deviceId = deviceId,
       _createSocketServer = createSocketServer;

  final String? _deviceId;

  DaemonConnection connection;

  final Logger _logger;

  final CreateSocketServer _createSocketServer;

  @override
  List<ForwardedPort> get forwardedPorts => _hostPortToForwardedPorts.values.toList();

  final Map<int, _ProxiedForwardedPort> _hostPortToForwardedPorts = <int, _ProxiedForwardedPort>{};

  final List<Socket> _connectedSockets = <Socket>[];

  @override
  Future<int> forward(int devicePort, {int? hostPort, bool? ipv6}) async {
    int? remoteDevicePort;
    final String? deviceId = _deviceId;

    // If deviceId is set, we need to forward the remote device port to remote host as well.
    // And then, forward the remote host port to a local host port.
    if (deviceId != null) {
      final Map<String, Object?> result = _cast<Map<String, Object?>>(
        await connection.sendRequest('device.forward', <String, Object>{
          'deviceId': deviceId,
          'devicePort': devicePort,
        }));
      remoteDevicePort = devicePort;
      devicePort = result['hostPort']! as int;
    }

    final ServerSocket serverSocket = await _startProxyServer(devicePort, hostPort, ipv6);

    _hostPortToForwardedPorts[serverSocket.port] = _ProxiedForwardedPort(
      connection,
      hostPort: serverSocket.port,
      devicePort: devicePort,
      remoteDevicePort: remoteDevicePort,
      deviceId: deviceId,
      serverSocket: serverSocket,
    );

    return serverSocket.port;
  }

  Future<ServerSocket> _startProxyServer(int devicePort, int? hostPort, bool? ipv6) async {
    final ServerSocket serverSocket = await _createSocketServer(_logger, hostPort, ipv6);

    serverSocket.listen((Socket socket) async {
      final String id = _cast<String>(await connection.sendRequest('proxy.connect', <String, Object>{
        'port': devicePort,
      }));
      final Stream<List<int>> dataStream = connection.listenToEvent('proxy.data.$id').asyncExpand((DaemonEventData event) => event.binary);
      dataStream.listen(socket.add);
      final Future<DaemonEventData> disconnectFuture = connection.listenToEvent('proxy.disconnected.$id').first;
      unawaited(disconnectFuture.then<void>((_) async {
          try {
            await socket.close();
          } on Exception {
            // ignore
          }
        },
        onError: (_) {
          // The event is not guaranteed to be sent if we initiated the disconnection.
          // Do nothing here.
        },
      ));
      debounceDataStream(socket).listen((Uint8List data) {
        unawaited(connection.sendRequest('proxy.write', <String, Object>{
          'id': id,
        }, data).then(
          (Object? obj) => obj,
          onError: (Object error, StackTrace stackTrace) {
            // Log the error, but proceed normally. Network failure should not
            // crash the tool. If this is critical, the place where the connection
            // is being used would crash.
            _logger.printWarning('Write to remote proxy error: $error');
            _logger.printTrace('Write to remote proxy error: $error, stack trace: $stackTrace');
            return null;
          },
        ));
      });
      _connectedSockets.add(socket);

      unawaited(socket.done.then(
        (Object? obj) => obj,
        onError: (Object error, StackTrace stackTrace) {
        // Do nothing here. Everything will be handled in the `then` block below.
        return false;
      }).whenComplete(() {
        // Send a proxy disconnect event just in case.
        unawaited(connection.sendRequest('proxy.disconnect', <String, Object>{
          'id': id,
        }).then(
          (Object? obj) => obj,
          onError: (Object error, StackTrace stackTrace) {
            // Ignore the error here. There might be a race condition when the
            // remote end also disconnects. In any case, this request is just to
            // notify the remote end to disconnect and we should not crash when
            // there is an error here.
            return null;
          },
        ));
        _connectedSockets.remove(socket);
      }));
    }, onError: (Object error, StackTrace stackTrace) {
      _logger.printWarning('Server socket error: $error');
      _logger.printTrace('Server socket error: $error, stack trace: $stackTrace');
    });

    return serverSocket;
  }

  @override
  Future<void> unforward(ForwardedPort forwardedPort) async {
    // Look for the forwarded port entry in our own map.
    final _ProxiedForwardedPort? proxiedForwardedPort = _hostPortToForwardedPorts.remove(forwardedPort.hostPort);
    await proxiedForwardedPort?.unforward();
  }

  @override
  Future<void> dispose() async {
    for (final _ProxiedForwardedPort forwardedPort in _hostPortToForwardedPorts.values) {
      await forwardedPort.unforward();
    }

    await Future.wait(<Future<void>>[
      for (final Socket socket in _connectedSockets)
        socket.close(),
    ]);
  }

  /// Returns the original remote port given the local port.
  ///
  /// If this is not a port that is handled by this port forwarder, return null.
  int? originalRemotePort(int localForwardedPort) {
    return _hostPortToForwardedPorts[localForwardedPort]?.devicePort;
  }
}

Future<ServerSocket> _defaultCreateServerSocket(Logger logger, int? hostPort, bool? ipv6) async {
  if (ipv6 == null || !ipv6) {
    try {
      return await ServerSocket.bind(InternetAddress.loopbackIPv4, hostPort ?? 0);
    } on SocketException {
      logger.printTrace('Bind on $hostPort failed with IPv4, retrying on IPv6');
    }
  }

  // If binding on ipv4 failed, try binding on ipv6.
  // Omit try catch here, let the failure fallthrough.
  return ServerSocket.bind(InternetAddress.loopbackIPv6, hostPort ?? 0);
}

/// A class that starts the [DartDevelopmentService] on the daemon.
///
/// There are a lot of communications between DDS and the VM service on the
/// device. When using proxied device, starting DDS remotely helps reduces the
/// amount of data transferred with the remote daemon, hence improving latency.
class ProxiedDartDevelopmentService implements DartDevelopmentService {
  ProxiedDartDevelopmentService(
    this.connection,
    this.deviceId, {
    required Logger logger,
    required ProxiedPortForwarder proxiedPortForwarder,
    required ProxiedPortForwarder devicePortForwarder,
    @visibleForTesting DartDevelopmentService? localDds,
  })  : _logger = logger,
        _proxiedPortForwarder = proxiedPortForwarder,
        _devicePortForwarder = devicePortForwarder,
        _localDds = localDds ?? DartDevelopmentService();

  final String deviceId;

  final Logger _logger;

  /// [DaemonConnection] used to communicate with the daemon.
  final DaemonConnection connection;

  /// [_proxiedPortForwarder] matches the [proxiedPortForwarder] of a ProxiedDevice.
  /// It forwards a port on the remote host to the local host.
  final ProxiedPortForwarder _proxiedPortForwarder;

  /// [_devicePortForwarder] matches the [portForwarder] of a ProxiedDevice.
  /// It forwards a port on the remotely connected device, to the remote host, then to the local host.
  final ProxiedPortForwarder _devicePortForwarder;

  Uri? _localUri;

  @override
  Uri? get uri => _ddsStartedLocally ? _localDds.uri : _localUri;

  @override
  Future<void> get done => _completer.future;
  final Completer<void> _completer = Completer<void>();

  final DartDevelopmentService _localDds;

  bool _ddsStartedLocally = false;

  @override
  Future<void> startDartDevelopmentService(
    Uri vmServiceUri, {
    required Logger logger,
    int? hostPort,
    bool? ipv6,
    bool? disableServiceAuthCodes,
    bool cacheStartupProfile = false,
  }) async {
    // Locate the original VM service port on the remote daemon.
    // A proxied device has two PortForwarder. Check both to determine which
    // one forwarded the VM service port.
    final int? remoteVMServicePort =
        _proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ??
        _devicePortForwarder.originalRemotePort(vmServiceUri.port);

    if (remoteVMServicePort == null) {
      _logger.printTrace('VM service port is not a forwarded port. Start DDS locally.');
      _ddsStartedLocally = true;
      await _localDds.startDartDevelopmentService(
        vmServiceUri,
        logger: logger,
        hostPort: hostPort,
        ipv6: ipv6,
        disableServiceAuthCodes: disableServiceAuthCodes,
        cacheStartupProfile: cacheStartupProfile,
      );
      unawaited(_localDds.done.then(_completer.complete));
      return;
    }

    final Uri remoteVMServiceUri = vmServiceUri.replace(port: remoteVMServicePort);

    String? remoteUriStr;
    const String method = 'device.startDartDevelopmentService';
    try {
      // Proxies the `done` future.
      unawaited(connection
          .listenToEvent('device.dds.done.$deviceId')
          .first
          .then(
            (DaemonEventData event) => _completer.complete(),
            onError: (_) {
              // Ignore if we did not receive any event from the server.
            },
          ));
      remoteUriStr = _cast<String?>(await connection.sendRequest(method, <String, Object?>{
        'deviceId': deviceId,
        'vmServiceUri': remoteVMServiceUri.toString(),
        'disableServiceAuthCodes': disableServiceAuthCodes,
      }));
    } on String catch (e) {
      if (!e.contains(method)) {
        rethrow;
      }
      // Remote daemon does not support the command, ignore.
      // We will try to start DDS locally below.
    }

    if (remoteUriStr == null) {
      _logger.printTrace('Remote daemon cannot start DDS. Start a local DDS instead.');
      _ddsStartedLocally = true;
      await _localDds.startDartDevelopmentService(
        vmServiceUri,
        logger: logger,
        hostPort: hostPort,
        ipv6: ipv6,
        disableServiceAuthCodes: disableServiceAuthCodes,
        cacheStartupProfile: cacheStartupProfile,
      );
      unawaited(_localDds.done.then(_completer.complete));
      return;
    }

    _logger.printTrace('Remote DDS started on $remoteUriStr.');

    // Forward the port.
    final Uri remoteUri = Uri.parse(remoteUriStr);
    final int localPort = await _proxiedPortForwarder.forward(
      remoteUri.port,
      hostPort: hostPort,
      ipv6: ipv6,
    );

    _localUri = remoteUri.replace(port: localPort);
    _logger.printTrace('Local port forwarded DDS on $_localUri.');
    _logger.sendEvent('device.proxied_dds_forwarded', <String, String>{
      'deviceId': deviceId,
      'remoteUri': remoteUri.toString(),
      'localUri': _localUri!.toString(),
    });
  }

  @override
  Future<void> shutdown() async {
    if (_ddsStartedLocally) {
      await _localDds.shutdown();
      _ddsStartedLocally = false;
    } else {
      await connection.sendRequest('device.shutdownDartDevelopmentService', <String, Object?>{
        'deviceId': deviceId,
      });
    }
  }

  @override
  void setExternalDevToolsUri(Uri uri) {
    connection.sendRequest('device.setExternalDevToolsUriForDartDevelopmentService', <String, Object?>{
      'deviceId': deviceId,
      'uri': uri.toString(),
    });
  }
}

class ProxiedVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach {
  ProxiedVMServiceDiscoveryForAttach(
    this.connection,
    this.deviceId, {
    required this.proxiedPortForwarder,
    required this.fallbackDiscovery,
    this.appId,
    this.fuchsiaModule,
    this.filterDevicePort,
    this.expectedHostPort,
    required this.ipv6,
    required this.logger,
  });

  /// [DaemonConnection] used to communicate with the daemon.
  final DaemonConnection connection;

  final String deviceId;

  final String? appId;
  final String? fuchsiaModule;
  final int? filterDevicePort;
  final int? expectedHostPort;
  final bool ipv6;
  final Logger logger;

  final ProxiedPortForwarder proxiedPortForwarder;

  VMServiceDiscoveryForAttach Function() fallbackDiscovery;

  Stream<Uri>? _uris;

  @override
  Stream<Uri> get uris {
    if (_uris == null) {
      String? requestId;
      final StreamController<Uri> controller = StreamController<Uri>();

      controller.onListen = () {
        connection.sendRequest('device.startVMServiceDiscoveryForAttach', <String, Object?>{
          'deviceId': deviceId,
          'appId': appId,
          'fuchsiaModule': fuchsiaModule,
          'filterDevicePort': filterDevicePort,
          'ipv6': ipv6,
        }).then(
          (Object? response) async {
            requestId = _cast<String>(response);
            final Stream<Uri> vmService = connection
                .listenToEvent('device.VMServiceDiscoveryForAttach.$requestId')
                .asyncMap((DaemonEventData event) async {
              // Forward the port.
              final Uri remoteUri = Uri.parse(_cast<String>(event.data));
              final int port = remoteUri.port;
              final int localPort = await proxiedPortForwarder.forward(port, hostPort: expectedHostPort, ipv6: ipv6);
              return remoteUri.replace(port: localPort);
            });
            await controller.addStream(vmService);
          },
          onError: (Object e) {
            // Daemon throws string types.
            if (e is String && e.contains('command not understood')) {
              // Use a fallback if the daemon does not support VM service discovery.
              controller.addStream(fallbackDiscovery().uris);
            } else {
              controller.addError(e);
            }
          },
        );
      };
      controller.onCancel = () {
        if (requestId != null) {
          connection.sendRequest('device.stopVMServiceDiscoveryForAttach', <String, Object?>{'id': requestId});
        }
      };
      _uris = controller.stream;
    }
    return _uris!;
  }
}
