// 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:fake_async/fake_async.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/utils.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:test/fake.dart';

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

void main() {
  group('DeviceManager', () {
    testWithoutContext('getDevices', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      final FakeDevice device3 = FakeDevice('iPod touch', '82564b38861a9a5');
      final List<Device> devices = <Device>[device1, device2, device3];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );

      expect(await deviceManager.getDevices(), devices);
    });

    testWithoutContext('getDeviceById exact matcher', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      final FakeDevice device3 = FakeDevice('iPod touch', '82564b38861a9a5');
      final List<Device> devices = <Device>[device1, device2, device3];
      final BufferLogger logger = BufferLogger.test();

      // Include different device discoveries:
      // 1. One that never completes to prove the first exact match is
      // returned quickly.
      // 2. One that throws, to prove matches can return when some succeed
      // and others fail.
      // 3. A device discoverer that succeeds.
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        deviceDiscoveryOverrides: <DeviceDiscovery>[
          ThrowingPollingDeviceDiscovery(),
          LongPollingDeviceDiscovery(),
        ],
        logger: logger,
      );

      Future<void> expectDevice(String id, List<Device> expected) async {
        expect(await deviceManager.getDevicesById(id), expected);
      }
      await expectDevice('01abfc49119c410e', <Device>[device2]);
      expect(logger.traceText, contains('Ignored error discovering 01abfc49119c410e'));
      await expectDevice('Nexus 5X', <Device>[device2]);
      expect(logger.traceText, contains('Ignored error discovering Nexus 5X'));
      await expectDevice('0553790d0a4e726f', <Device>[device1]);
      expect(logger.traceText, contains('Ignored error discovering 0553790d0a4e726f'));
    });

    testWithoutContext('getDeviceById exact matcher with well known ID', () async {
      final FakeDevice device1 = FakeDevice('Windows', 'windows');
      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      final FakeDevice device3 = FakeDevice('iPod touch', '82564b38861a9a5');
      final List<Device> devices = <Device>[device1, device2, device3];
      final BufferLogger logger = BufferLogger.test();

      // Because the well known ID will match, no other device discovery will run.
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        deviceDiscoveryOverrides: <DeviceDiscovery>[
          ThrowingPollingDeviceDiscovery(),
          LongPollingDeviceDiscovery(),
        ],
        logger: logger,
        wellKnownId: 'windows',
      );

      Future<void> expectDevice(String id, List<Device> expected) async {
        deviceManager.specifiedDeviceId = id;
        expect(await deviceManager.getDevicesById(id), expected);
      }
      await expectDevice('windows', <Device>[device1]);
      expect(logger.traceText, isEmpty);
    });

    testWithoutContext('getDeviceById prefix matcher', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      final FakeDevice device3 = FakeDevice('iPod touch', '82564b38861a9a5');
      final List<Device> devices = <Device>[device1, device2, device3];
      final BufferLogger logger = BufferLogger.test();

      // Include different device discoveries:
      // 1. One that throws, to prove matches can return when some succeed
      // and others fail.
      // 2. A device discoverer that succeeds.
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        deviceDiscoveryOverrides: <DeviceDiscovery>[
          ThrowingPollingDeviceDiscovery(),
        ],
        logger: logger,
      );

      Future<void> expectDevice(String id, List<Device> expected) async {
        expect(await deviceManager.getDevicesById(id), expected);
      }
      await expectDevice('Nexus 5', <Device>[device1]);
      expect(logger.traceText, contains('Ignored error discovering Nexus 5'));
      await expectDevice('0553790', <Device>[device1]);
      expect(logger.traceText, contains('Ignored error discovering 0553790'));
      await expectDevice('Nexus', <Device>[device1, device2]);
      expect(logger.traceText, contains('Ignored error discovering Nexus'));
    });

    testWithoutContext('getDeviceById two exact matches, matches on first', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final FakeDevice device2 = FakeDevice('Nexus 5', '01abfc49119c410e');
      final List<Device> devices = <Device>[device1, device2];
      final BufferLogger logger = BufferLogger.test();

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: logger,
      );

      Future<void> expectDevice(String id, List<Device> expected) async {
        expect(await deviceManager.getDevicesById(id), expected);
      }
      await expectDevice('Nexus 5', <Device>[device1]);
    });

    testWithoutContext('getAllDevices caches', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final TestDeviceManager deviceManager = TestDeviceManager(
        <Device>[device1],
        logger: BufferLogger.test(),
      );
      expect(await deviceManager.getAllDevices(), <Device>[device1]);

      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      deviceManager.resetDevices(<Device>[device2]);
      expect(await deviceManager.getAllDevices(), <Device>[device1]);
    });

    testWithoutContext('refreshAllDevices does not cache', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final TestDeviceManager deviceManager = TestDeviceManager(
        <Device>[device1],
        logger: BufferLogger.test(),
      );
      expect(await deviceManager.refreshAllDevices(), <Device>[device1]);

      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      deviceManager.resetDevices(<Device>[device2]);
      expect(await deviceManager.refreshAllDevices(), <Device>[device2]);
    });
  });

  testWithoutContext('PollingDeviceDiscovery startPolling', () {
    FakeAsync().run((FakeAsync time) {
      final FakePollingDeviceDiscovery pollingDeviceDiscovery = FakePollingDeviceDiscovery();
      pollingDeviceDiscovery.startPolling();
      time.elapse(const Duration(milliseconds: 4001));

      // First check should use the default polling timeout
      // to quickly populate the list.
      expect(pollingDeviceDiscovery.lastPollingTimeout, isNull);

      time.elapse(const Duration(milliseconds: 4001));

      // Subsequent polling should be much longer.
      expect(pollingDeviceDiscovery.lastPollingTimeout, const Duration(seconds: 30));
      pollingDeviceDiscovery.stopPolling();
    });
  });

  group('Filter devices', () {
    final FakeDevice ephemeralOne = FakeDevice('ephemeralOne', 'ephemeralOne');
    final FakeDevice ephemeralTwo = FakeDevice('ephemeralTwo', 'ephemeralTwo');
    final FakeDevice nonEphemeralOne = FakeDevice('nonEphemeralOne', 'nonEphemeralOne', ephemeral: false);
    final FakeDevice nonEphemeralTwo = FakeDevice('nonEphemeralTwo', 'nonEphemeralTwo', ephemeral: false);
    final FakeDevice unsupported = FakeDevice('unsupported', 'unsupported', isSupported: false);
    final FakeDevice unsupportedForProject = FakeDevice('unsupportedForProject', 'unsupportedForProject', isSupportedForProject: false);
    final FakeDevice webDevice = FakeDevice('webby', 'webby')
      ..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.web_javascript);
    final FakeDevice fuchsiaDevice = FakeDevice('fuchsiay', 'fuchsiay')
      ..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.fuchsia_x64);
    final FakeDevice unconnectedDevice = FakeDevice('ephemeralTwo', 'ephemeralTwo', isConnected: false);
    final FakeDevice wirelessDevice = FakeDevice('ephemeralTwo', 'ephemeralTwo', connectionInterface: DeviceConnectionInterface.wireless);

    testUsingContext('chooses ephemeral device', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );

      final Device? ephemeralDevice = deviceManager.getSingleEphemeralDevice(devices);

      expect(ephemeralDevice, ephemeralOne);
    }, overrides: <Type, Generator>{
      FlutterProject: () => FakeFlutterProject(),
    });

    testUsingContext('returns null when multiple non ephemeral devices are found', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        ephemeralTwo,
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );

      final Device? ephemeralDevice = deviceManager.getSingleEphemeralDevice(devices);

      expect(ephemeralDevice, isNull);
    }, overrides: <Type, Generator>{
      FlutterProject: () => FakeFlutterProject(),
    });

    testUsingContext('return null when hasSpecifiedDeviceId is true', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = 'device';

      final Device? ephemeralDevice = deviceManager.getSingleEphemeralDevice(devices);

      expect(ephemeralDevice, isNull);
    }, overrides: <Type, Generator>{
      FlutterProject: () => FakeFlutterProject(),
    });

    testUsingContext('returns null when no ephemeral devices are found', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );

      final Device? ephemeralDevice = deviceManager.getSingleEphemeralDevice(devices);

      expect(ephemeralDevice, isNull);
    }, overrides: <Type, Generator>{
      FlutterProject: () => FakeFlutterProject(),
    });

    testWithoutContext('Unsupported devices listed in all devices', () async {
      final List<Device> devices = <Device>[
        unsupported,
        unsupportedForProject,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final List<Device> filtered = await deviceManager.getDevices();

      expect(filtered, <Device>[
        unsupported,
        unsupportedForProject,
      ]);
    });

    testUsingContext('Removes unsupported devices', () async {
      final List<Device> devices = <Device>[
        unsupported,
        unsupportedForProject,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[]);
    });

    testUsingContext('Retains devices unsupported by the project if includeDevicesUnsupportedByProject is true', () async {
      final List<Device> devices = <Device>[
        unsupported,
        unsupportedForProject,
      ];

      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(
            includeDevicesUnsupportedByProject: true,
          ),
        ),
      );

      expect(filtered, <Device>[unsupportedForProject]);
    });

    testUsingContext('Removes web and fuchsia from --all', () async {
      final List<Device> devices = <Device>[
        webDevice,
        fuchsiaDevice,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = 'all';

      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[]);
    });

    testUsingContext('Removes devices unsupported by the project from --all', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
        unsupported,
        unsupportedForProject,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = 'all';

      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ]);
    });

    testUsingContext('Returns device with the specified id', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = nonEphemeralOne.id;

      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[
        nonEphemeralOne,
      ]);
    });

    testUsingContext('Returns multiple devices when multiple devices matches the specified id', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = 'nonEphemeral'; // This prefix matches both devices

      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ]);
    });

    testUsingContext('Returns empty when device of specified id is not found', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      deviceManager.specifiedDeviceId = nonEphemeralTwo.id;

      final List<Device> filtered = await deviceManager.getDevices(
        filter: DeviceDiscoveryFilter(
          supportFilter: deviceManager.deviceSupportFilter(),
        ),
      );

      expect(filtered, <Device>[]);
    });

    testWithoutContext('uses DeviceDiscoverySupportFilter.isDeviceSupportedForProject instead of device.isSupportedForProject', () async {
      final List<Device> devices = <Device>[
        unsupported,
        unsupportedForProject,
      ];
      final TestDeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final TestDeviceDiscoverySupportFilter supportFilter =
          TestDeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject(
        flutterProject: FakeFlutterProject(),
      );
      supportFilter.isAlwaysSupportedForProjectOverride = true;
      final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
        supportFilter: supportFilter,
      );

      final List<Device> filtered = await deviceManager.getDevices(
        filter: filter,
      );

      expect(filtered, <Device>[
        unsupportedForProject,
      ]);
    });

    testUsingContext('Unconnencted devices filtered out by default', () async {
      final List<Device> devices = <Device>[
        unconnectedDevice,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );

      final List<Device> filtered = await deviceManager.getDevices();

      expect(filtered, <Device>[]);
    });

    testUsingContext('Return unconnected devices when filter allows', () async {
      final List<Device> devices = <Device>[
        unconnectedDevice,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
        excludeDisconnected: false,
      );

      final List<Device> filtered = await deviceManager.getDevices(
        filter: filter,
      );

      expect(filtered, <Device>[unconnectedDevice]);
    });

    testUsingContext('Filter to only include wireless devices', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        wirelessDevice,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
        deviceConnectionInterface: DeviceConnectionInterface.wireless,
      );

      final List<Device> filtered = await deviceManager.getDevices(
        filter: filter,
      );

      expect(filtered, <Device>[wirelessDevice]);
    });

    testUsingContext('Filter to only include attached devices', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        wirelessDevice,
      ];
      final DeviceManager deviceManager = TestDeviceManager(
        devices,
        logger: BufferLogger.test(),
      );
      final DeviceDiscoveryFilter filter = DeviceDiscoveryFilter(
        deviceConnectionInterface: DeviceConnectionInterface.attached,
      );

      final List<Device> filtered = await deviceManager.getDevices(
        filter: filter,
      );

      expect(filtered, <Device>[ephemeralOne]);
    });
  });



  group('Simultaneous device discovery', () {
    testWithoutContext('Run getAllDevices and refreshAllDevices at same time with refreshAllDevices finishing last', () async {
      FakeAsync().run((FakeAsync time) {
        final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
        final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');

        const Duration timeToGetInitialDevices = Duration(seconds: 1);
        const Duration timeToRefreshDevices = Duration(seconds: 5);
        final List<Device> initialDevices = <Device>[device2];
        final List<Device> refreshDevices = <Device>[device1];

        final TestDeviceManager deviceManager = TestDeviceManager(
          <Device>[],
          logger: BufferLogger.test(),
          fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
            <List<Device>>[
              initialDevices,
              refreshDevices,
            ],
            timeout: timeToGetInitialDevices,
          ),
        );

        // Expect that the cache is set by getOrSetCache process (1 second timeout)
        // and then later updated by refreshCache process (5 second timeout).
        // Ending with devices from the refreshCache process.
        final Future<List<Device>> refreshCache = deviceManager.refreshAllDevices(
          timeout: timeToRefreshDevices,
        );
        final Future<List<Device>> getOrSetCache = deviceManager.getAllDevices();

        // After 1 second, the getAllDevices should be done
        time.elapse(const Duration(seconds: 1));
        expect(getOrSetCache, completion(<Device>[device2]));
        // double check values in cache are as expected
        Future<List<Device>> getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device2]));

        // After 5 seconds, getOrSetCache should be done
        time.elapse(const Duration(seconds: 5));
        expect(refreshCache, completion(<Device>[device1]));
        // double check values in cache are as expected
        getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device1]));

        time.flushMicrotasks();
      });
    });

    testWithoutContext('Run getAllDevices and refreshAllDevices at same time with refreshAllDevices finishing first', () async {
      fakeAsync((FakeAsync async) {
        final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
        final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');

        const Duration timeToGetInitialDevices = Duration(seconds: 5);
        const Duration timeToRefreshDevices = Duration(seconds: 1);
        final List<Device> initialDevices = <Device>[device2];
        final List<Device> refreshDevices = <Device>[device1];

        final TestDeviceManager deviceManager = TestDeviceManager(
          <Device>[],
          logger: BufferLogger.test(),
          fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
            <List<Device>>[
              initialDevices,
              refreshDevices,
            ],
            timeout: timeToGetInitialDevices,
          ),
        );

        // Expect that the cache is set by refreshCache process (1 second timeout).
        // Then later when getOrSetCache finishes (5 second timeout), it does not update the cache.
        // Ending with devices from the refreshCache process.
        final Future<List<Device>> refreshCache = deviceManager.refreshAllDevices(
          timeout: timeToRefreshDevices,
        );
        final Future<List<Device>> getOrSetCache = deviceManager.getAllDevices();

        // After 1 second, the refreshCache should be done
        async.elapse(const Duration(seconds: 1));
        expect(refreshCache, completion(<Device>[device2]));
        // double check values in cache are as expected
        Future<List<Device>> getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device2]));

        // After 5 seconds, getOrSetCache should be done
        async.elapse(const Duration(seconds: 5));
        expect(getOrSetCache, completion(<Device>[device2]));
        // double check values in cache are as expected
        getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device2]));

        async.flushMicrotasks();
      });
    });

    testWithoutContext('refreshAllDevices twice', () async {
      fakeAsync((FakeAsync async) {
        final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
        final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');

        const Duration timeToFirstRefresh = Duration(seconds: 1);
        const Duration timeToSecondRefresh = Duration(seconds: 5);
        final List<Device> firstRefreshDevices = <Device>[device2];
        final List<Device> secondRefreshDevices = <Device>[device1];

        final TestDeviceManager deviceManager = TestDeviceManager(
          <Device>[],
          logger: BufferLogger.test(),
          fakeDiscoverer: FakePollingDeviceDiscoveryWithTimeout(
            <List<Device>>[
              firstRefreshDevices,
              secondRefreshDevices,
            ],
          ),
        );

        // Expect that the cache is updated by each refresh in order of completion.
        final Future<List<Device>> firstRefresh = deviceManager.refreshAllDevices(
          timeout: timeToFirstRefresh,
        );
        final Future<List<Device>> secondRefresh = deviceManager.refreshAllDevices(
          timeout: timeToSecondRefresh,
        );

        // After 1 second, the firstRefresh should be done
        async.elapse(const Duration(seconds: 1));
        expect(firstRefresh, completion(<Device>[device2]));
        // double check values in cache are as expected
        Future<List<Device>> getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device2]));

        // After 5 seconds, secondRefresh should be done
        async.elapse(const Duration(seconds: 5));
        expect(secondRefresh, completion(<Device>[device1]));
        // double check values in cache are as expected
        getFromCache = deviceManager.getAllDevices();
        expect(getFromCache, completion(<Device>[device1]));

        async.flushMicrotasks();
      });
    });
  });

  group('JSON encode devices', () {
    testWithoutContext('Consistency of JSON representation', () async {
      expect(
        // This tests that fakeDevices is a list of tuples where "second" is the
        // correct JSON representation of the "first". Actual values are irrelevant
        await Future.wait(fakeDevices.map((FakeDeviceJsonData d) => d.dev.toJson())),
        fakeDevices.map((FakeDeviceJsonData d) => d.json)
      );
    });
  });

  testWithoutContext('computeDartVmFlags handles various combinations of Dart VM flags and null_assertions', () {
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug)), '');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo')), '--foo');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, nullAssertions: true)), '--null_assertions');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo', nullAssertions: true)), '--foo,--null_assertions');
  });

  group('JSON encode DebuggingOptions', () {
    testWithoutContext('can preserve the original options', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
        startPaused: true,
        disableServiceAuthCodes: true,
        enableDds: false,
        dartEntrypointArgs: <String>['a', 'b'],
        dartFlags: 'c',
        deviceVmServicePort: 1234,
        enableImpeller: ImpellerStatus.enabled,
        enableDartProfiling: false,
        enableEmbedderApi: true,
      );
      final String jsonString = json.encode(original.toJson());
      final Map<String, dynamic> decoded = castStringKeyedMap(json.decode(jsonString))!;
      final DebuggingOptions deserialized = DebuggingOptions.fromJson(decoded, BuildInfo.debug);
      expect(deserialized.startPaused, original.startPaused);
      expect(deserialized.disableServiceAuthCodes, original.disableServiceAuthCodes);
      expect(deserialized.enableDds, original.enableDds);
      expect(deserialized.dartEntrypointArgs, original.dartEntrypointArgs);
      expect(deserialized.dartFlags, original.dartFlags);
      expect(deserialized.deviceVmServicePort, original.deviceVmServicePort);
      expect(deserialized.enableImpeller, original.enableImpeller);
      expect(deserialized.enableDartProfiling, original.enableDartProfiling);
      expect(deserialized.enableEmbedderApi, original.enableEmbedderApi);
    });
  });

  group('Get iOS launch arguments from DebuggingOptions', () {
    testWithoutContext('Get launch arguments for physical device with debugging enabled with all launch arguments', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
        startPaused: true,
        disableServiceAuthCodes: true,
        disablePortPublication: true,
        dartFlags: '--foo',
        useTestFonts: true,
        enableSoftwareRendering: true,
        skiaDeterministicRendering: true,
        traceSkia: true,
        traceAllowlist: 'foo',
        traceSkiaAllowlist: 'skia.a,skia.b',
        traceSystrace: true,
        endlessTraceBuffer: true,
        dumpSkpOnShaderCompilation: true,
        cacheSkSL: true,
        purgePersistentCache: true,
        verboseSystemLogs: true,
        enableImpeller: ImpellerStatus.disabled,
        nullAssertions: true,
        deviceVmServicePort: 0,
        hostVmServicePort: 1,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        '/test',
        <String, dynamic>{
          'trace-startup': true,
        },
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--disable-service-auth-codes',
          '--disable-vm-service-publication',
          '--start-paused',
          '--dart-flags="--foo,--null_assertions"',
          '--use-test-fonts',
          '--enable-checked-mode',
          '--verify-entry-points',
          '--enable-software-rendering',
          '--trace-systrace',
          '--skia-deterministic-rendering',
          '--trace-skia',
          '--trace-allowlist="foo"',
          '--trace-skia-allowlist="skia.a,skia.b"',
          '--endless-trace-buffer',
          '--dump-skp-on-shader-compilation',
          '--verbose-logging',
          '--cache-sksl',
          '--purge-persistent-cache',
          '--route=/test',
          '--trace-startup',
          '--enable-impeller=false',
          '--vm-service-port=0',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for physical device with debugging enabled with no launch arguments', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        null,
        <String, Object?>{},
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--enable-checked-mode',
          '--verify-entry-points',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for physical device with iPv4 network connection', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        null,
        <String, Object?>{},
        interfaceType: DeviceConnectionInterface.wireless,
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--enable-checked-mode',
          '--verify-entry-points',
          '--vm-service-host=0.0.0.0',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for physical device with iPv6 network connection', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        null,
        <String, Object?>{},
        ipv6: true,
        interfaceType: DeviceConnectionInterface.wireless,
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--enable-checked-mode',
          '--verify-entry-points',
          '--vm-service-host=::0',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for physical device with debugging disabled with available launch arguments', () {
      final DebuggingOptions original = DebuggingOptions.disabled(
        BuildInfo.debug,
        traceAllowlist: 'foo',
        cacheSkSL: true,
        enableImpeller: ImpellerStatus.disabled,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        '/test',
        <String, dynamic>{
          'trace-startup': true,
        },
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--trace-allowlist="foo"',
          '--cache-sksl',
          '--route=/test',
          '--trace-startup',
          '--enable-impeller=false',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for simulator device with debugging enabled with all launch arguments', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
        startPaused: true,
        disableServiceAuthCodes: true,
        disablePortPublication: true,
        dartFlags: '--foo',
        useTestFonts: true,
        enableSoftwareRendering: true,
        skiaDeterministicRendering: true,
        traceSkia: true,
        traceAllowlist: 'foo',
        traceSkiaAllowlist: 'skia.a,skia.b',
        traceSystrace: true,
        endlessTraceBuffer: true,
        dumpSkpOnShaderCompilation: true,
        cacheSkSL: true,
        purgePersistentCache: true,
        verboseSystemLogs: true,
        enableImpeller: ImpellerStatus.disabled,
        nullAssertions: true,
        deviceVmServicePort: 0,
        hostVmServicePort: 1,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.simulator,
        '/test',
        <String, dynamic>{
          'trace-startup': true,
        },
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--disable-service-auth-codes',
          '--disable-vm-service-publication',
          '--start-paused',
          '--dart-flags=--foo,--null_assertions',
          '--use-test-fonts',
          '--enable-checked-mode',
          '--verify-entry-points',
          '--enable-software-rendering',
          '--trace-systrace',
          '--skia-deterministic-rendering',
          '--trace-skia',
          '--trace-allowlist="foo"',
          '--trace-skia-allowlist="skia.a,skia.b"',
          '--endless-trace-buffer',
          '--dump-skp-on-shader-compilation',
          '--verbose-logging',
          '--cache-sksl',
          '--purge-persistent-cache',
          '--route=/test',
          '--trace-startup',
          '--enable-impeller=false',
          '--vm-service-port=1',
        ].join(' '),
      );
    });

    testWithoutContext('Get launch arguments for simulator device with debugging enabled with no launch arguments', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.simulator,
        null,
        <String, Object?>{},
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-dart-profiling',
          '--enable-checked-mode',
          '--verify-entry-points',
        ].join(' '),
      );
    });

    testWithoutContext('No --enable-dart-profiling flag when option is false', () {
      final DebuggingOptions original = DebuggingOptions.enabled(
        BuildInfo.debug,
        enableDartProfiling: false,
      );

      final List<String> launchArguments = original.getIOSLaunchArguments(
        EnvironmentType.physical,
        null,
        <String, Object?>{},
      );

      expect(
        launchArguments.join(' '),
        <String>[
          '--enable-checked-mode',
          '--verify-entry-points',
        ].join(' '),
      );
    });
  });
}

class TestDeviceManager extends DeviceManager {
  TestDeviceManager(
    List<Device> allDevices, {
    List<DeviceDiscovery>? deviceDiscoveryOverrides,
    required super.logger,
    String? wellKnownId,
    FakePollingDeviceDiscovery? fakeDiscoverer,
  }) : _fakeDeviceDiscoverer = fakeDiscoverer ?? FakePollingDeviceDiscovery(),
       _deviceDiscoverers = <DeviceDiscovery>[],
       super() {
    if (wellKnownId != null) {
      _fakeDeviceDiscoverer.wellKnownIds.add(wellKnownId);
    }
    _deviceDiscoverers.add(_fakeDeviceDiscoverer);
    if (deviceDiscoveryOverrides != null) {
      _deviceDiscoverers.addAll(deviceDiscoveryOverrides);
    }
    resetDevices(allDevices);
  }
  @override
  List<DeviceDiscovery> get deviceDiscoverers => _deviceDiscoverers;
  final List<DeviceDiscovery> _deviceDiscoverers;
  final FakePollingDeviceDiscovery _fakeDeviceDiscoverer;

  void resetDevices(List<Device> allDevices) {
    _fakeDeviceDiscoverer.setDevices(allDevices);
  }
}

class MockDeviceDiscovery extends Fake implements DeviceDiscovery {
  int devicesCalled = 0;
  int discoverDevicesCalled = 0;

  @override
  bool supportsPlatform = true;

  List<Device> deviceValues = <Device>[];

  @override
  Future<List<Device>> devices({DeviceDiscoveryFilter? filter}) async {
    devicesCalled += 1;
    return deviceValues;
  }

  @override
  Future<List<Device>> discoverDevices({
    Duration? timeout,
    DeviceDiscoveryFilter? filter,
  }) async {
    discoverDevicesCalled += 1;
    return deviceValues;
  }

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

class TestDeviceDiscoverySupportFilter extends DeviceDiscoverySupportFilter {
  TestDeviceDiscoverySupportFilter.excludeDevicesUnsupportedByFlutterOrProject({
    required super.flutterProject,
  }) : super.excludeDevicesUnsupportedByFlutterOrProject();


  bool? isAlwaysSupportedForProjectOverride;

  @override
  bool isDeviceSupportedForProject(Device device) {
    if (isAlwaysSupportedForProjectOverride != null) {
      return isAlwaysSupportedForProjectOverride!;
    }
    return super.isDeviceSupportedForProject(device);
  }
}

class FakePollingDeviceDiscoveryWithTimeout extends FakePollingDeviceDiscovery {
  FakePollingDeviceDiscoveryWithTimeout(
    this._devices, {
    Duration? timeout,
  }): defaultTimeout = timeout ?? const Duration(seconds: 2);

  final List<List<Device>> _devices;
  int index = 0;

  Duration defaultTimeout;
  @override
  Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
    timeout ??= defaultTimeout;
    await Future<void>.delayed(timeout);
    final List<Device> results = _devices[index];
    index += 1;
    return results;
  }
}

class FakeFlutterProject extends Fake implements FlutterProject { }

class LongPollingDeviceDiscovery extends PollingDeviceDiscovery {
  LongPollingDeviceDiscovery() : super('forever');

  final Completer<List<Device>> _completer = Completer<List<Device>>();

  @override
  Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
    return _completer.future;
  }

  @override
  Future<void> stopPolling() async {
    _completer.complete(<Device>[]);
  }

  @override
  Future<void> dispose() async {
    _completer.complete(<Device>[]);
  }

  @override
  bool get supportsPlatform => true;

  @override
  bool get canListAnything => true;

  @override
  final List<String> wellKnownIds = <String>[];
}

class ThrowingPollingDeviceDiscovery extends PollingDeviceDiscovery {
  ThrowingPollingDeviceDiscovery() : super('throw');

  @override
  Future<List<Device>> pollingGetDevices({ Duration? timeout }) async {
    throw const ProcessException('fake-discovery', <String>[]);
  }

  @override
  bool get supportsPlatform => true;

  @override
  bool get canListAnything => true;

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