// 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:io' as io;

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwarder.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/macos/xcdevice.dart';
import 'package:test/fake.dart';

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

void main() {
  final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos');
  final FakePlatform linuxPlatform = FakePlatform();
  final FakePlatform windowsPlatform = FakePlatform(operatingSystem: 'windows');

  group('IOSDevice', () {
    final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
    late Cache cache;
    late Logger logger;
    late IOSDeploy iosDeploy;
    late IMobileDevice iMobileDevice;
    late FileSystem fileSystem;

    setUp(() {
      final Artifacts artifacts = Artifacts.test();
      cache = Cache.test(processManager: FakeProcessManager.any());
      logger = BufferLogger.test();
      fileSystem = MemoryFileSystem.test();
      iosDeploy = IOSDeploy(
        artifacts: artifacts,
        cache: cache,
        logger: logger,
        platform: macPlatform,
        processManager: FakeProcessManager.any(),
      );
      iMobileDevice = IMobileDevice(
        artifacts: artifacts,
        cache: cache,
        logger: logger,
        processManager: FakeProcessManager.any(),
      );
    });

    testWithoutContext('successfully instantiates on Mac OS', () {
      final IOSDevice device = IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        sdkVersion: '13.3',
        cpuArchitecture: DarwinArch.arm64,
        interfaceType: IOSDeviceConnectionInterface.usb,
      );
      expect(device.isSupported(), isTrue);
    });

    testWithoutContext('32-bit devices are unsupported', () {
      final IOSDevice device = IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.armv7,
        interfaceType: IOSDeviceConnectionInterface.usb,
      );
      expect(device.isSupported(), isFalse);
    });

    testWithoutContext('parses major version', () {
      expect(IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.arm64,
        sdkVersion: '1.0.0',
        interfaceType: IOSDeviceConnectionInterface.usb,
      ).majorSdkVersion, 1);
      expect(IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.arm64,
        sdkVersion: '13.1.1',
        interfaceType: IOSDeviceConnectionInterface.usb,
      ).majorSdkVersion, 13);
      expect(IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.arm64,
        sdkVersion: '10',
        interfaceType: IOSDeviceConnectionInterface.usb,
      ).majorSdkVersion, 10);
      expect(IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.arm64,
        sdkVersion: '0',
        interfaceType: IOSDeviceConnectionInterface.usb,
      ).majorSdkVersion, 0);
      expect(IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        cpuArchitecture: DarwinArch.arm64,
        sdkVersion: 'bogus',
        interfaceType: IOSDeviceConnectionInterface.usb,
      ).majorSdkVersion, 0);
    });

    testWithoutContext('has build number in sdkNameAndVersion', () async {
      final IOSDevice device = IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        sdkVersion: '13.3 17C54',
        cpuArchitecture: DarwinArch.arm64,
        interfaceType: IOSDeviceConnectionInterface.usb,
      );

      expect(await device.sdkNameAndVersion,'iOS 13.3 17C54');
    });

    testWithoutContext('Supports debug, profile, and release modes', () {
      final IOSDevice device = IOSDevice(
        'device-123',
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        fileSystem: fileSystem,
        logger: logger,
        platform: macPlatform,
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        name: 'iPhone 1',
        sdkVersion: '13.3',
        cpuArchitecture: DarwinArch.arm64,
        interfaceType: IOSDeviceConnectionInterface.usb,
      );

      expect(device.supportsRuntimeMode(BuildMode.debug), true);
      expect(device.supportsRuntimeMode(BuildMode.profile), true);
      expect(device.supportsRuntimeMode(BuildMode.release), true);
      expect(device.supportsRuntimeMode(BuildMode.jitRelease), false);
    });

    for (final Platform platform in unsupportedPlatforms) {
      testWithoutContext('throws UnsupportedError exception if instantiated on ${platform.operatingSystem}', () {
        expect(
          () {
            IOSDevice(
              'device-123',
              iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
              fileSystem: fileSystem,
              logger: logger,
              platform: platform,
              iosDeploy: iosDeploy,
              iMobileDevice: iMobileDevice,
              name: 'iPhone 1',
              sdkVersion: '13.3',
              cpuArchitecture: DarwinArch.arm64,
              interfaceType: IOSDeviceConnectionInterface.usb,
            );
          },
          throwsAssertionError,
        );
      });
    }

    group('.dispose()', () {
      late IOSDevice device;
      late FakeIOSApp appPackage1;
      late FakeIOSApp appPackage2;
      late IOSDeviceLogReader logReader1;
      late IOSDeviceLogReader logReader2;
      late FakeProcess process1;
      late FakeProcess process2;
      late FakeProcess process3;
      late IOSDevicePortForwarder portForwarder;
      late ForwardedPort forwardedPort;
      late Cache cache;
      late Logger logger;
      late IOSDeploy iosDeploy;
      late FileSystem fileSystem;
      late IProxy iproxy;

      IOSDevicePortForwarder createPortForwarder(
          ForwardedPort forwardedPort,
          IOSDevice device) {
        iproxy = IProxy.test(logger: logger, processManager: FakeProcessManager.any());
        final IOSDevicePortForwarder portForwarder = IOSDevicePortForwarder(
          id: device.id,
          logger: logger,
          operatingSystemUtils: OperatingSystemUtils(
            fileSystem: fileSystem,
            logger: logger,
            platform: FakePlatform(operatingSystem: 'macos'),
            processManager: FakeProcessManager.any(),
          ),
          iproxy: iproxy,
        );
        portForwarder.addForwardedPorts(<ForwardedPort>[forwardedPort]);
        return portForwarder;
      }

      IOSDeviceLogReader createLogReader(
          IOSDevice device,
          IOSApp appPackage,
          Process process) {
        final IOSDeviceLogReader logReader = IOSDeviceLogReader.create(
          device: device,
          app: appPackage,
          iMobileDevice: IMobileDevice.test(processManager: FakeProcessManager.any()),
        );
        logReader.idevicesyslogProcess = process;
        return logReader;
      }

      setUp(() {
        appPackage1 = FakeIOSApp('flutterApp1');
        appPackage2 = FakeIOSApp('flutterApp2');
        process1 = FakeProcess();
        process2 = FakeProcess();
        process3 = FakeProcess();
        forwardedPort = ForwardedPort.withContext(123, 456, process3);
        cache = Cache.test(
          processManager: FakeProcessManager.any(),
        );
        fileSystem = MemoryFileSystem.test();
        logger = BufferLogger.test();
        iosDeploy = IOSDeploy(
          artifacts: Artifacts.test(),
          cache: cache,
          logger: logger,
          platform: macPlatform,
          processManager: FakeProcessManager.any(),
        );
      });

      testWithoutContext('kills all log readers & port forwarders', () async {
        device = IOSDevice(
          '123',
          iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
          fileSystem: fileSystem,
          logger: logger,
          platform: macPlatform,
          iosDeploy: iosDeploy,
          iMobileDevice: iMobileDevice,
          name: 'iPhone 1',
          sdkVersion: '13.3',
          cpuArchitecture: DarwinArch.arm64,
          interfaceType: IOSDeviceConnectionInterface.usb,
        );
        logReader1 = createLogReader(device, appPackage1, process1);
        logReader2 = createLogReader(device, appPackage2, process2);
        portForwarder = createPortForwarder(forwardedPort, device);
        device.setLogReader(appPackage1, logReader1);
        device.setLogReader(appPackage2, logReader2);
        device.portForwarder = portForwarder;

        await device.dispose();

        expect(process1.killed, true);
        expect(process2.killed, true);
        expect(process3.killed, true);
      });
    });
  });

  group('polling', () {
    late FakeXcdevice xcdevice;
    late Cache cache;
    late FakeProcessManager fakeProcessManager;
    late BufferLogger logger;
    late IOSDeploy iosDeploy;
    late IMobileDevice iMobileDevice;
    late IOSWorkflow iosWorkflow;
    late IOSDevice device1;
    late IOSDevice device2;

    setUp(() {
      xcdevice = FakeXcdevice();
      final Artifacts artifacts = Artifacts.test();
      cache = Cache.test(processManager: FakeProcessManager.any());
      logger = BufferLogger.test();
      iosWorkflow = FakeIOSWorkflow();
      fakeProcessManager = FakeProcessManager.any();
      iosDeploy = IOSDeploy(
        artifacts: artifacts,
        cache: cache,
        logger: logger,
        platform: macPlatform,
        processManager: fakeProcessManager,
      );
      iMobileDevice = IMobileDevice(
        artifacts: artifacts,
        cache: cache,
        processManager: fakeProcessManager,
        logger: logger,
      );

      device1 = IOSDevice(
        'd83d5bc53967baa0ee18626ba87b6254b2ab5418',
        name: 'Paired iPhone',
        sdkVersion: '13.3',
        cpuArchitecture: DarwinArch.arm64,
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        logger: logger,
        platform: macPlatform,
        fileSystem: MemoryFileSystem.test(),
        interfaceType: IOSDeviceConnectionInterface.usb,
      );

      device2 = IOSDevice(
        '00008027-00192736010F802E',
        name: 'iPad Pro',
        sdkVersion: '13.3',
        cpuArchitecture: DarwinArch.arm64,
        iProxy: IProxy.test(logger: logger, processManager: FakeProcessManager.any()),
        iosDeploy: iosDeploy,
        iMobileDevice: iMobileDevice,
        logger: logger,
        platform: macPlatform,
        fileSystem: MemoryFileSystem.test(),
        interfaceType: IOSDeviceConnectionInterface.usb,
      );
    });

    testWithoutContext('start polling without Xcode', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = false;

      await iosDevices.startPolling();
      expect(xcdevice.getAvailableIOSDevicesCount, 0);
    });

    testWithoutContext('start polling', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = true;
      xcdevice.devices
        ..add(<IOSDevice>[])
        ..add(<IOSDevice>[device1, device2]);

      int addedCount = 0;
      final Completer<void> added = Completer<void>();
      iosDevices.onAdded.listen((Device device) {
        addedCount++;
        // 2 devices will be added.
        // Will throw over-completion if called more than twice.
        if (addedCount >= 2) {
          added.complete();
        }
      });

      final Completer<void> removed = Completer<void>();
      iosDevices.onRemoved.listen((Device device) {
        // Will throw over-completion if called more than once.
        removed.complete();
      });

      await iosDevices.startPolling();
      expect(xcdevice.getAvailableIOSDevicesCount, 1);

      expect(iosDevices.deviceNotifier!.items, isEmpty);
      expect(xcdevice.deviceEventController.hasListener, isTrue);

      xcdevice.deviceEventController.add(<XCDeviceEvent, String>{
        XCDeviceEvent.attach: 'd83d5bc53967baa0ee18626ba87b6254b2ab5418'
      });
      await added.future;
      expect(iosDevices.deviceNotifier!.items.length, 2);
      expect(iosDevices.deviceNotifier!.items, contains(device1));
      expect(iosDevices.deviceNotifier!.items, contains(device2));

      xcdevice.deviceEventController.add(<XCDeviceEvent, String>{
        XCDeviceEvent.detach: 'd83d5bc53967baa0ee18626ba87b6254b2ab5418'
      });
      await removed.future;
      expect(iosDevices.deviceNotifier!.items, <Device>[device2]);

      // Remove stream will throw over-completion if called more than once
      // which proves this is ignored.
      xcdevice.deviceEventController.add(<XCDeviceEvent, String>{
        XCDeviceEvent.detach: 'bogus'
      });

      expect(addedCount, 2);

      await iosDevices.stopPolling();

      expect(xcdevice.deviceEventController.hasListener, isFalse);
    });

    testWithoutContext('polling can be restarted if stream is closed', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = true;
      xcdevice.devices.add(<IOSDevice>[]);
      xcdevice.devices.add(<IOSDevice>[]);

      final StreamController<Map<XCDeviceEvent, String>> rescheduledStream = StreamController<Map<XCDeviceEvent, String>>();

      unawaited(xcdevice.deviceEventController.done.whenComplete(() {
        xcdevice.deviceEventController = rescheduledStream;
      }));

      await iosDevices.startPolling();
      expect(xcdevice.deviceEventController.hasListener, isTrue);
      expect(xcdevice.getAvailableIOSDevicesCount, 1);

      // Pretend xcdevice crashed.
      await xcdevice.deviceEventController.close();
      expect(logger.traceText, contains('xcdevice observe stopped'));

      // Confirm a restart still gets streamed events.
      await iosDevices.startPolling();

      expect(rescheduledStream.hasListener, isTrue);

      await iosDevices.stopPolling();
      expect(rescheduledStream.hasListener, isFalse);
    });

    testWithoutContext('dispose cancels polling subscription', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = true;
      xcdevice.devices.add(<IOSDevice>[]);

      await iosDevices.startPolling();
      expect(iosDevices.deviceNotifier!.items, isEmpty);
      expect(xcdevice.deviceEventController.hasListener, isTrue);

      iosDevices.dispose();
      expect(xcdevice.deviceEventController.hasListener, isFalse);
    });

    final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
    for (final Platform unsupportedPlatform in unsupportedPlatforms) {
      testWithoutContext('pollingGetDevices throws Unsupported Operation exception on ${unsupportedPlatform.operatingSystem}', () async {
        final IOSDevices iosDevices = IOSDevices(
          platform: unsupportedPlatform,
          xcdevice: xcdevice,
          iosWorkflow: iosWorkflow,
          logger: logger,
        );
        xcdevice.isInstalled = false;
        expect(
          () async { await iosDevices.pollingGetDevices(); },
          throwsUnsupportedError,
        );
      });
    }

    testWithoutContext('pollingGetDevices returns attached devices', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = true;
      xcdevice.devices.add(<IOSDevice>[device1]);

      final List<Device> devices = await iosDevices.pollingGetDevices();

      expect(devices, hasLength(1));
      expect(devices.first, same(device1));
    });
  });

  group('getDiagnostics', () {
    late FakeXcdevice xcdevice;
    late IOSWorkflow iosWorkflow;
    late Logger logger;

    setUp(() {
      xcdevice = FakeXcdevice();
      iosWorkflow = FakeIOSWorkflow();
      logger = BufferLogger.test();
    });

    final List<Platform> unsupportedPlatforms = <Platform>[linuxPlatform, windowsPlatform];
    for (final Platform unsupportedPlatform in unsupportedPlatforms) {
      testWithoutContext('throws returns platform diagnostic exception on ${unsupportedPlatform.operatingSystem}', () async {
        final IOSDevices iosDevices = IOSDevices(
          platform: unsupportedPlatform,
          xcdevice: xcdevice,
          iosWorkflow: iosWorkflow,
          logger: logger,
        );
        xcdevice.isInstalled = false;
        expect((await iosDevices.getDiagnostics()).first, 'Control of iOS devices or simulators only supported on macOS.');
      });
    }

    testWithoutContext('returns diagnostics', () async {
      final IOSDevices iosDevices = IOSDevices(
        platform: macPlatform,
        xcdevice: xcdevice,
        iosWorkflow: iosWorkflow,
        logger: logger,
      );
      xcdevice.isInstalled = true;
      xcdevice.diagnostics.add('Generic pairing error');

      final List<String> diagnostics = await iosDevices.getDiagnostics();
      expect(diagnostics, hasLength(1));
      expect(diagnostics.first, 'Generic pairing error');
    });
  });
}

class FakeIOSApp extends Fake implements IOSApp {
  FakeIOSApp(this.name);

  @override
  final String name;
}

class FakeIOSWorkflow extends Fake implements IOSWorkflow { }

class FakeXcdevice extends Fake implements XCDevice {
  int getAvailableIOSDevicesCount = 0;
  final List<List<IOSDevice>> devices = <List<IOSDevice>>[];
  final List<String> diagnostics = <String>[];
  StreamController<Map<XCDeviceEvent, String>> deviceEventController = StreamController<Map<XCDeviceEvent, String>>();

  @override
  bool isInstalled = true;

  @override
  Future<List<String>> getDiagnostics() async {
    return diagnostics;
  }

  @override
  Stream<Map<XCDeviceEvent, String>> observedDeviceEvents() {
    return deviceEventController.stream;
  }

  @override
  Future<List<IOSDevice>> getAvailableIOSDevices({Duration? timeout}) async {
    return devices[getAvailableIOSDevicesCount++];
  }
}

class FakeProcess extends Fake implements Process {
  bool killed = false;

  @override
  bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) {
    killed = true;
    return true;
  }
}
