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

import 'base/logger.dart';
import 'device.dart';
import 'device_port_forwarder.dart';
import 'mdns_discovery.dart';
import 'protocol_discovery.dart';

/// Discovers the VM service uri on a device, and forwards the port to the host.
///
/// This is mainly used during a `flutter attach`.
abstract class VMServiceDiscoveryForAttach {
  VMServiceDiscoveryForAttach();

  /// The discovered VM service URis.
  ///
  /// Port forwarding is only attempted when this is invoked, for each VM
  /// Service URI in the stream.
  Stream<Uri> get uris;
}

/// An implementation of [VMServiceDiscoveryForAttach] that uses log scanning
/// for the discovery.
class LogScanningVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach {
  LogScanningVMServiceDiscoveryForAttach(
    Future<DeviceLogReader> logReader, {
    DevicePortForwarder? portForwarder,
    int? hostPort,
    int? devicePort,
    required bool ipv6,
    required Logger logger,
  }) {
    _protocolDiscovery = (() async => ProtocolDiscovery.vmService(
      await logReader,
      portForwarder: portForwarder,
      ipv6: ipv6,
      devicePort: devicePort,
      hostPort: hostPort,
      logger: logger,
    ))();
  }

  late final Future<ProtocolDiscovery> _protocolDiscovery;

  @override
  Stream<Uri> get uris {
    final StreamController<Uri> controller = StreamController<Uri>();
    _protocolDiscovery.then(
      (ProtocolDiscovery protocolDiscovery) async {
        await controller.addStream(protocolDiscovery.uris);
        await controller.close();
      },
      onError: (Object error) => controller.addError(error),
    );
    return controller.stream;
  }
}

/// An implementation of [VMServiceDiscoveryForAttach] that uses mdns for the
/// discovery.
class MdnsVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach {
  MdnsVMServiceDiscoveryForAttach({
    required this.device,
    this.appId,
    required this.usesIpv6,
    required this.useDeviceIPAsHost,
    this.deviceVmservicePort,
    this.hostVmservicePort,
  });

  final Device device;
  final String? appId;
  final bool usesIpv6;
  final bool useDeviceIPAsHost;
  final int? deviceVmservicePort;
  final int? hostVmservicePort;

  @override
  Stream<Uri> get uris {
    final Future<Uri?> mDNSDiscoveryFuture = MDnsVmServiceDiscovery.instance!.getVMServiceUriForAttach(
      appId,
      device,
      usesIpv6: usesIpv6,
      useDeviceIPAsHost: useDeviceIPAsHost,
      deviceVmservicePort: deviceVmservicePort,
      hostVmservicePort: hostVmservicePort,
    );

    return Stream<Uri?>.fromFuture(mDNSDiscoveryFuture).where((Uri? uri) => uri != null).cast<Uri>().asBroadcastStream();
  }
}

/// An implementation of [VMServiceDiscoveryForAttach] that delegates to other
/// [VMServiceDiscoveryForAttach] instances for discovery.
class DelegateVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach {
  DelegateVMServiceDiscoveryForAttach(this.delegates);

  final List<VMServiceDiscoveryForAttach> delegates;

  @override
  Stream<Uri> get uris =>
      StreamGroup.merge<Uri>(
        delegates.map((VMServiceDiscoveryForAttach delegate) => delegate.uris));
}
