// 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:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/mdns_discovery.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:multicast_dns/multicast_dns.dart';
import 'package:test/fake.dart';

import '../src/common.dart';

void main() {
  group('mDNS Discovery', () {
    final int future = DateTime.now().add(const Duration(days: 1)).millisecondsSinceEpoch;

    setUp(() {
      setNetworkInterfaceLister(
        ({
          bool? includeLoopback,
          bool? includeLinkLocal,
          InternetAddressType? type,
        }) async => <NetworkInterface>[],
      );
    });

    tearDown(() {
      resetNetworkInterfaceLister();
    });

    group('for attach', () {
      late MDnsClient emptyClient;

      setUp(() {
        emptyClient = FakeMDnsClient(<PtrResourceRecord>[], <String, List<SrvResourceRecord>>{});
      });

      testWithoutContext('Find result in preliminary client', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        final MDnsVmServiceDiscoveryResult? result = await portDiscovery.queryForAttach();
        expect(result, isNotNull);
      });

      testWithoutContext('Do not find result in preliminary client, but find in main client', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        final MDnsVmServiceDiscoveryResult? result = await portDiscovery.queryForAttach();
        expect(result, isNotNull);
      });

      testWithoutContext('Find multiple in preliminary client', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
            PtrResourceRecord('baz', future, domainName: 'fiz'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
            'fiz': <SrvResourceRecord>[
              SrvResourceRecord('fiz', future, port: 321, weight: 1, priority: 1, target: 'local'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        expect(portDiscovery.queryForAttach, throwsToolExit());
      });

      testWithoutContext('Find duplicates in preliminary client', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        final MDnsVmServiceDiscoveryResult? result = await portDiscovery.queryForAttach();
        expect(result, isNotNull);
      });

      testWithoutContext('Find similar named in preliminary client', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
            PtrResourceRecord('foo', future, domainName: 'bar (2)'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
            'bar (2)': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        expect(portDiscovery.queryForAttach, throwsToolExit());
      });

      testWithoutContext('No ports available', () async {
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        final int? port = (await portDiscovery.queryForAttach())?.port;
        expect(port, isNull);
      });

      testWithoutContext('Prints helpful message when there is no ipv4 link local address.', () async {
        final BufferLogger logger = BufferLogger.test();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: emptyClient,
          preliminaryMDnsClient: emptyClient,
          logger: logger,
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForAttach(
          '',
          FakeIOSDevice(),
        );
        expect(uri, isNull);
        expect(logger.errorText, contains('Personal Hotspot'));
      });

      testWithoutContext('One port available, no appId', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final int? port = (await portDiscovery.queryForAttach())?.port;
        expect(port, 123);
      });

      testWithoutContext('One port available, no appId, with authCode', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
          txtResponse: <String, List<TxtResourceRecord>>{
            'bar': <TxtResourceRecord>[
              TxtResourceRecord('bar', future, text: 'authCode=xyz\n'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final MDnsVmServiceDiscoveryResult? result = await portDiscovery.queryForAttach();
        expect(result?.port, 123);
        expect(result?.authCode, 'xyz/');
      });

      testWithoutContext('Multiple ports available, with appId', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
            PtrResourceRecord('baz', future, domainName: 'fiz'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
            'fiz': <SrvResourceRecord>[
              SrvResourceRecord('fiz', future, port: 321, weight: 1, priority: 1, target: 'local'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final int? port = (await portDiscovery.queryForAttach(applicationId: 'fiz'))?.port;
        expect(port, 321);
      });

      testWithoutContext('Multiple ports available per process, with appId', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
            PtrResourceRecord('baz', future, domainName: 'fiz'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 1234, weight: 1, priority: 1, target: 'appId'),
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
            'fiz': <SrvResourceRecord>[
              SrvResourceRecord('fiz', future, port: 4321, weight: 1, priority: 1, target: 'local'),
              SrvResourceRecord('fiz', future, port: 321, weight: 1, priority: 1, target: 'local'),
            ],
          },
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final int? port = (await portDiscovery.queryForAttach(applicationId: 'bar'))?.port;
        expect(port, 1234);
      });

      testWithoutContext('Throws Exception when client throws OSError on start', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[], <String, List<SrvResourceRecord>>{},
          osErrorOnStart: true,
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        expect(
          () async => portDiscovery.queryForAttach(),
          throwsException,
        );
      });

      testWithoutContext('Correctly builds VM Service URI with hostVmservicePort == 0', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForAttach('bar', device, hostVmservicePort: 0);
        expect(uri.toString(), 'http://127.0.0.1:123/');
      });

      testWithoutContext('Get network device IP (iPv4)', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 1234, weight: 1, priority: 1, target: 'appId'),
            ],
          },
          ipResponse: <String, List<IPAddressResourceRecord>>{
            'appId': <IPAddressResourceRecord>[
              IPAddressResourceRecord('Device IP', 0, address: InternetAddress.tryParse('111.111.111.111')!),
            ],
          },
          txtResponse: <String, List<TxtResourceRecord>>{
            'bar': <TxtResourceRecord>[
              TxtResourceRecord('bar', future, text: 'authCode=xyz\n'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForAttach(
          'bar',
          device,
          isNetworkDevice: true,
        );
        expect(uri.toString(), 'http://111.111.111.111:1234/xyz/');
      });

      testWithoutContext('Get network device IP (iPv6)', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 1234, weight: 1, priority: 1, target: 'appId'),
            ],
          },
          ipResponse: <String, List<IPAddressResourceRecord>>{
            'appId': <IPAddressResourceRecord>[
              IPAddressResourceRecord('Device IP', 0, address: InternetAddress.tryParse('1111:1111:1111:1111:1111:1111:1111:1111')!),
            ],
          },
          txtResponse: <String, List<TxtResourceRecord>>{
            'bar': <TxtResourceRecord>[
              TxtResourceRecord('bar', future, text: 'authCode=xyz\n'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForAttach(
          'bar',
          device,
          isNetworkDevice: true,
        );
        expect(uri.toString(), 'http://[1111:1111:1111:1111:1111:1111:1111:1111]:1234/xyz/');
      });

      testWithoutContext('Throw error if unable to find VM service with app id and device port', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'srv-foo'),
            PtrResourceRecord('bar', future, domainName: 'srv-bar'),
            PtrResourceRecord('baz', future, domainName: 'srv-boo'),
          ],
          <String, List<SrvResourceRecord>>{
            'srv-foo': <SrvResourceRecord>[
              SrvResourceRecord('srv-foo', future, port: 123, weight: 1, priority: 1, target: 'target-foo'),
            ],
            'srv-bar': <SrvResourceRecord>[
              SrvResourceRecord('srv-bar', future, port: 123, weight: 1, priority: 1, target: 'target-bar'),
            ],
            'srv-baz': <SrvResourceRecord>[
              SrvResourceRecord('srv-baz', future, port: 123, weight: 1, priority: 1, target: 'target-baz'),
            ],
          },
        );
        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        expect(
          portDiscovery.getVMServiceUriForAttach(
            'srv-bar',
            device,
            deviceVmservicePort: 321,
          ),
          throwsToolExit(
            message: 'Did not find a Dart VM Service advertised for srv-bar on port 321.'
          ),
        );
      });

      testWithoutContext('Throw error if unable to find VM Service with app id', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'srv-foo'),
          ],
          <String, List<SrvResourceRecord>>{
            'srv-foo': <SrvResourceRecord>[
              SrvResourceRecord('srv-foo', future, port: 123, weight: 1, priority: 1, target: 'target-foo'),
            ],
          },
        );
        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          preliminaryMDnsClient: emptyClient,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        expect(
          portDiscovery.getVMServiceUriForAttach(
            'srv-asdf',
            device,
          ),
          throwsToolExit(
            message: 'Did not find a Dart VM Service advertised for srv-asdf.'
          ),
        );
      });
    });

    group('for launch', () {
      testWithoutContext('No ports available', () async {
        final MDnsClient client = FakeMDnsClient(<PtrResourceRecord>[], <String, List<SrvResourceRecord>>{});

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );

        final MDnsVmServiceDiscoveryResult? result = await portDiscovery.queryForLaunch(
          applicationId: 'app-id',
          deviceVmservicePort: 123,
        );

        expect(result, null);
      });

      testWithoutContext('Prints helpful message when there is no ipv4 link local address.', () async {
        final MDnsClient client = FakeMDnsClient(<PtrResourceRecord>[], <String, List<SrvResourceRecord>>{});
        final BufferLogger logger = BufferLogger.test();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: logger,
          flutterUsage: TestUsage(),
        );

        final Uri? uri = await portDiscovery.getVMServiceUriForLaunch(
          '',
          FakeIOSDevice(),
          deviceVmservicePort: 0,
        );
        expect(uri, isNull);
        expect(logger.errorText, contains('Personal Hotspot'));
      });

      testWithoutContext('Throws Exception when client throws OSError on start', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[], <String, List<SrvResourceRecord>>{},
          osErrorOnStart: true,
        );

        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        expect(
          () async => portDiscovery.queryForLaunch(applicationId: 'app-id', deviceVmservicePort: 123),
          throwsException,
        );
      });

      testWithoutContext('Correctly builds VM Service URI with hostVmservicePort == 0', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 123, weight: 1, priority: 1, target: 'appId'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForLaunch(
          'bar',
          device,
          hostVmservicePort: 0,
          deviceVmservicePort: 123,
        );
        expect(uri.toString(), 'http://127.0.0.1:123/');
      });

      testWithoutContext('Get network device IP (iPv4)', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 1234, weight: 1, priority: 1, target: 'appId'),
            ],
          },
          ipResponse: <String, List<IPAddressResourceRecord>>{
            'appId': <IPAddressResourceRecord>[
              IPAddressResourceRecord('Device IP', 0, address: InternetAddress.tryParse('111.111.111.111')!),
            ],
          },
          txtResponse: <String, List<TxtResourceRecord>>{
            'bar': <TxtResourceRecord>[
              TxtResourceRecord('bar', future, text: 'authCode=xyz\n'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForLaunch(
          'bar',
          device,
          isNetworkDevice: true,
          deviceVmservicePort: 1234,
        );
        expect(uri.toString(), 'http://111.111.111.111:1234/xyz/');
      });

      testWithoutContext('Get network device IP (iPv6)', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'bar'),
          ],
          <String, List<SrvResourceRecord>>{
            'bar': <SrvResourceRecord>[
              SrvResourceRecord('bar', future, port: 1234, weight: 1, priority: 1, target: 'appId'),
            ],
          },
          ipResponse: <String, List<IPAddressResourceRecord>>{
            'appId': <IPAddressResourceRecord>[
              IPAddressResourceRecord('Device IP', 0, address: InternetAddress.tryParse('1111:1111:1111:1111:1111:1111:1111:1111')!),
            ],
          },
          txtResponse: <String, List<TxtResourceRecord>>{
            'bar': <TxtResourceRecord>[
              TxtResourceRecord('bar', future, text: 'authCode=xyz\n'),
            ],
          },
        );

        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        final Uri? uri = await portDiscovery.getVMServiceUriForLaunch(
          'bar',
          device,
          isNetworkDevice: true,
          deviceVmservicePort: 1234,
        );
        expect(uri.toString(), 'http://[1111:1111:1111:1111:1111:1111:1111:1111]:1234/xyz/');
      });

      testWithoutContext('Throw error if unable to find VM Service with app id and device port', () async {
        final MDnsClient client = FakeMDnsClient(
          <PtrResourceRecord>[
            PtrResourceRecord('foo', future, domainName: 'srv-foo'),
            PtrResourceRecord('bar', future, domainName: 'srv-bar'),
            PtrResourceRecord('baz', future, domainName: 'srv-boo'),
          ],
          <String, List<SrvResourceRecord>>{
            'srv-foo': <SrvResourceRecord>[
              SrvResourceRecord('srv-foo', future, port: 123, weight: 1, priority: 1, target: 'target-foo'),
            ],
            'srv-bar': <SrvResourceRecord>[
              SrvResourceRecord('srv-bar', future, port: 123, weight: 1, priority: 1, target: 'target-bar'),
            ],
            'srv-baz': <SrvResourceRecord>[
              SrvResourceRecord('srv-baz', future, port: 123, weight: 1, priority: 1, target: 'target-baz'),
            ],
          },
        );
        final FakeIOSDevice device = FakeIOSDevice();
        final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
          mdnsClient: client,
          logger: BufferLogger.test(),
          flutterUsage: TestUsage(),
        );
        expect(
          portDiscovery.getVMServiceUriForLaunch(
            'srv-bar',
            device,
            deviceVmservicePort: 321,
          ),
          throwsToolExit(
              message:'Did not find a Dart VM Service advertised for srv-bar on port 321.'),
        );
      });
    });

    testWithoutContext('Find firstMatchingVmService with many available and no application id', () async {
      final MDnsClient client = FakeMDnsClient(
        <PtrResourceRecord>[
          PtrResourceRecord('foo', future, domainName: 'srv-foo'),
          PtrResourceRecord('bar', future, domainName: 'srv-bar'),
          PtrResourceRecord('baz', future, domainName: 'srv-boo'),
        ],
        <String, List<SrvResourceRecord>>{
          'srv-foo': <SrvResourceRecord>[
            SrvResourceRecord('srv-foo', future, port: 123, weight: 1, priority: 1, target: 'target-foo'),
          ],
          'srv-bar': <SrvResourceRecord>[
            SrvResourceRecord('srv-bar', future, port: 123, weight: 1, priority: 1, target: 'target-bar'),
          ],
          'srv-baz': <SrvResourceRecord>[
            SrvResourceRecord('srv-baz', future, port: 123, weight: 1, priority: 1, target: 'target-baz'),
          ],
        },
      );

      final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
        mdnsClient: client,
        logger: BufferLogger.test(),
        flutterUsage: TestUsage(),
      );
      final MDnsVmServiceDiscoveryResult? result = await portDiscovery.firstMatchingVmService(client);
      expect(result?.domainName, 'srv-foo');
    });

    testWithoutContext('Find firstMatchingVmService app id', () async {
      final MDnsClient client = FakeMDnsClient(
        <PtrResourceRecord>[
          PtrResourceRecord('foo', future, domainName: 'srv-foo'),
          PtrResourceRecord('bar', future, domainName: 'srv-bar'),
          PtrResourceRecord('baz', future, domainName: 'srv-boo'),
        ],
        <String, List<SrvResourceRecord>>{
          'srv-foo': <SrvResourceRecord>[
            SrvResourceRecord('srv-foo', future, port: 111, weight: 1, priority: 1, target: 'target-foo'),
          ],
          'srv-bar': <SrvResourceRecord>[
            SrvResourceRecord('srv-bar', future, port: 222, weight: 1, priority: 1, target: 'target-bar'),
            SrvResourceRecord('srv-bar', future, port: 333, weight: 1, priority: 1, target: 'target-bar-2'),
          ],
          'srv-baz': <SrvResourceRecord>[
            SrvResourceRecord('srv-baz', future, port: 444, weight: 1, priority: 1, target: 'target-baz'),
          ],
        },
      );

      final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
        mdnsClient: client,
        logger: BufferLogger.test(),
        flutterUsage: TestUsage(),
      );
      final MDnsVmServiceDiscoveryResult? result = await portDiscovery.firstMatchingVmService(
        client,
        applicationId: 'srv-bar'
      );
      expect(result?.domainName, 'srv-bar');
      expect(result?.port, 222);
    });
    testWithoutContext('find with no txt record', () async {
      final MDnsClient client = FakeMDnsClient(
        <PtrResourceRecord>[
          PtrResourceRecord('foo', future, domainName: 'srv-foo'),
        ],
        <String, List<SrvResourceRecord>>{
          'srv-foo': <SrvResourceRecord>[
            SrvResourceRecord('srv-foo', future, port: 111, weight: 1, priority: 1, target: 'target-foo'),
          ],
        },
        ipResponse: <String, List<IPAddressResourceRecord>>{
          'target-foo': <IPAddressResourceRecord>[
            IPAddressResourceRecord('target-foo', 0, address: InternetAddress.tryParse('111.111.111.111')!),
          ],
        },
      );

      final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
        mdnsClient: client,
        logger: BufferLogger.test(),
        flutterUsage: TestUsage(),
      );
      final MDnsVmServiceDiscoveryResult? result = await portDiscovery.firstMatchingVmService(
        client,
        applicationId: 'srv-foo',
        isNetworkDevice: true,
      );
      expect(result?.domainName, 'srv-foo');
      expect(result?.port, 111);
      expect(result?.authCode, '');
      expect(result?.ipAddress?.address, '111.111.111.111');
    });
    testWithoutContext('find with empty txt record', () async {
      final MDnsClient client = FakeMDnsClient(
        <PtrResourceRecord>[
          PtrResourceRecord('foo', future, domainName: 'srv-foo'),
        ],
        <String, List<SrvResourceRecord>>{
          'srv-foo': <SrvResourceRecord>[
            SrvResourceRecord('srv-foo', future, port: 111, weight: 1, priority: 1, target: 'target-foo'),
          ],
        },
        txtResponse: <String, List<TxtResourceRecord>>{
          'srv-foo': <TxtResourceRecord>[
            TxtResourceRecord('srv-foo', future, text: ''),
          ],
        },
        ipResponse: <String, List<IPAddressResourceRecord>>{
          'target-foo': <IPAddressResourceRecord>[
            IPAddressResourceRecord('target-foo', 0, address: InternetAddress.tryParse('111.111.111.111')!),
          ],
        },
      );

      final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
        mdnsClient: client,
        logger: BufferLogger.test(),
        flutterUsage: TestUsage(),
      );
      final MDnsVmServiceDiscoveryResult? result = await portDiscovery.firstMatchingVmService(
        client,
        applicationId: 'srv-foo',
        isNetworkDevice: true,
      );
      expect(result?.domainName, 'srv-foo');
      expect(result?.port, 111);
      expect(result?.authCode, '');
      expect(result?.ipAddress?.address, '111.111.111.111');
    });
    testWithoutContext('find with valid txt record', () async {
      final MDnsClient client = FakeMDnsClient(
        <PtrResourceRecord>[
          PtrResourceRecord('foo', future, domainName: 'srv-foo'),
        ],
        <String, List<SrvResourceRecord>>{
          'srv-foo': <SrvResourceRecord>[
            SrvResourceRecord('srv-foo', future, port: 111, weight: 1, priority: 1, target: 'target-foo'),
          ],
        },
        txtResponse: <String, List<TxtResourceRecord>>{
          'srv-foo': <TxtResourceRecord>[
            TxtResourceRecord('srv-foo', future, text: 'authCode=xyz\n'),
          ],
        },
        ipResponse: <String, List<IPAddressResourceRecord>>{
          'target-foo': <IPAddressResourceRecord>[
            IPAddressResourceRecord('target-foo', 0, address: InternetAddress.tryParse('111.111.111.111')!),
          ],
        },
      );

      final MDnsVmServiceDiscovery portDiscovery = MDnsVmServiceDiscovery(
        mdnsClient: client,
        logger: BufferLogger.test(),
        flutterUsage: TestUsage(),
      );
      final MDnsVmServiceDiscoveryResult? result = await portDiscovery.firstMatchingVmService(
        client,
        applicationId: 'srv-foo',
        isNetworkDevice: true,
      );
      expect(result?.domainName, 'srv-foo');
      expect(result?.port, 111);
      expect(result?.authCode, 'xyz/');
      expect(result?.ipAddress?.address, '111.111.111.111');
    });
  });
}

class FakeMDnsClient extends Fake implements MDnsClient {
  FakeMDnsClient(this.ptrRecords, this.srvResponse, {
    this.txtResponse = const <String, List<TxtResourceRecord>>{},
    this.ipResponse = const <String, List<IPAddressResourceRecord>>{},
    this.osErrorOnStart = false,
  });

  final List<PtrResourceRecord> ptrRecords;
  final Map<String, List<SrvResourceRecord>> srvResponse;
  final Map<String, List<TxtResourceRecord>> txtResponse;
  final Map<String, List<IPAddressResourceRecord>> ipResponse;
  final bool osErrorOnStart;

  @override
  Future<void> start({
    InternetAddress? listenAddress,
    NetworkInterfacesFactory? interfacesFactory,
    int mDnsPort = 5353,
    InternetAddress? mDnsAddress,
  }) async {
    if (osErrorOnStart) {
      throw const OSError('Operation not supported on socket', 102);
    }
  }

  @override
  Stream<T> lookup<T extends ResourceRecord>(
    ResourceRecordQuery query, {
    Duration timeout = const Duration(seconds: 5),
  }) {
    if (T == PtrResourceRecord && query.fullyQualifiedName == MDnsVmServiceDiscovery.dartVmServiceName) {
      return Stream<PtrResourceRecord>.fromIterable(ptrRecords) as Stream<T>;
    }
    if (T == SrvResourceRecord) {
      final String key = query.fullyQualifiedName;
      return Stream<SrvResourceRecord>.fromIterable(srvResponse[key] ?? <SrvResourceRecord>[]) as Stream<T>;
    }
    if (T == TxtResourceRecord) {
      final String key = query.fullyQualifiedName;
      return Stream<TxtResourceRecord>.fromIterable(txtResponse[key] ?? <TxtResourceRecord>[]) as Stream<T>;
    }
    if (T == IPAddressResourceRecord) {
      final String key = query.fullyQualifiedName;
      return Stream<IPAddressResourceRecord>.fromIterable(ipResponse[key] ?? <IPAddressResourceRecord>[]) as Stream<T>;
    }
    throw UnsupportedError('Unsupported query type $T');
  }

  @override
  void stop() {}
}

// Unfortunately Device, despite not being immutable, has an `operator ==`.
// Until we fix that, we have to also ignore related lints here.
// ignore: avoid_implementing_value_types
class FakeIOSDevice extends Fake implements IOSDevice {
  @override
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.ios;

  @override
  bool isSupported() => true;

  @override
  bool isSupportedForProject(FlutterProject flutterProject) => true;

  @override
  DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
}
