// 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:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/artifacts.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/base/io.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
import 'package:fake_async/fake_async.dart';
import 'package:flutter_tools/src/globals.dart' as globals;

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

void main() {
  MockCache cache;
  BufferLogger logger;

  setUp(() {
    cache = MockCache();
    logger = BufferLogger.test();
    when(cache.dyLdLibEntry).thenReturn(const MapEntry<String, String>('foo', 'bar'));
  });

  group('DeviceManager', () {
    testUsingContext('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);
      expect(await deviceManager.getDevices(), devices);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('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];

      // 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,
        testLongPollingDeviceDiscovery: true,
        testThrowingDeviceDiscovery: true,
      );

      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'));
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
      Logger: () => logger,
    });

    testUsingContext('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];

      // 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,
        testThrowingDeviceDiscovery: true
      );

      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'));
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
      Logger: () => logger,
    });

    testUsingContext('getAllConnectedDevices caches', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final TestDeviceManager deviceManager = TestDeviceManager(<Device>[device1]);
      expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);

      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      deviceManager.resetDevices(<Device>[device2]);
      expect(await deviceManager.getAllConnectedDevices(), <Device>[device1]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('refreshAllConnectedDevices does not cache', () async {
      final FakeDevice device1 = FakeDevice('Nexus 5', '0553790d0a4e726f');
      final TestDeviceManager deviceManager = TestDeviceManager(<Device>[device1]);
      expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device1]);

      final FakeDevice device2 = FakeDevice('Nexus 5X', '01abfc49119c410e');
      deviceManager.resetDevices(<Device>[device2]);
      expect(await deviceManager.refreshAllConnectedDevices(), <Device>[device2]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });
  });

  group('PollingDeviceDiscovery', () {
    testUsingContext('startPolling', () async {
      await FakeAsync().run((FakeAsync time) async {
        final FakePollingDeviceDiscovery pollingDeviceDiscovery = FakePollingDeviceDiscovery();
        await pollingDeviceDiscovery.startPolling();
        time.elapse(const Duration(milliseconds: 4001));
        time.flushMicrotasks();
        // First check should use the default polling timeout
        // to quickly populate the list.
        expect(pollingDeviceDiscovery.lastPollingTimeout, isNull);

        time.elapse(const Duration(milliseconds: 4001));
        time.flushMicrotasks();
        // Subsequent polling should be much longer.
        expect(pollingDeviceDiscovery.lastPollingTimeout, const Duration(seconds: 30));
        await pollingDeviceDiscovery.stopPolling();
      });
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    }, skip: true); // TODO(jonahwilliams): clean up with https://github.com/flutter/flutter/issues/60675
  });

  group('Filter devices', () {
    FakeDevice ephemeralOne;
    FakeDevice ephemeralTwo;
    FakeDevice nonEphemeralOne;
    FakeDevice nonEphemeralTwo;
    FakeDevice unsupported;
    FakeDevice webDevice;
    FakeDevice fuchsiaDevice;
    MockStdio mockStdio;

    setUp(() {
      ephemeralOne = FakeDevice('ephemeralOne', 'ephemeralOne', true);
      ephemeralTwo = FakeDevice('ephemeralTwo', 'ephemeralTwo', true);
      nonEphemeralOne = FakeDevice('nonEphemeralOne', 'nonEphemeralOne', false);
      nonEphemeralTwo = FakeDevice('nonEphemeralTwo', 'nonEphemeralTwo', false);
      unsupported = FakeDevice('unsupported', 'unsupported', true, false);
      webDevice = FakeDevice('webby', 'webby')
        ..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.web_javascript);
      fuchsiaDevice = FakeDevice('fuchsiay', 'fuchsiay')
        ..targetPlatform = Future<TargetPlatform>.value(TargetPlatform.fuchsia_x64);
      mockStdio = MockStdio();
    });

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

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered.single, ephemeralOne);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('choose first non-ephemeral device', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      when(mockStdio.stdinHasTerminal).thenReturn(true);
      when(globals.terminal.promptForCharInput(<String>['0', '1'],
      logger: globals.logger,
      prompt: globals.userMessages.flutterChooseOne)
      ).thenAnswer((Invocation invocation) async => '0');

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        nonEphemeralOne
      ]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Stdio: () => mockStdio,
      AnsiTerminal: () => MockTerminal(),
    });

    testUsingContext('choose second non-ephemeral device', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ];

      when(mockStdio.stdinHasTerminal).thenReturn(true);
      when(globals.terminal.promptForCharInput(<String>['0', '1'],
      logger: globals.logger,
      prompt: globals.userMessages.flutterChooseOne)
      ).thenAnswer((Invocation invocation) async => '1');

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        nonEphemeralTwo
      ]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Stdio: () => mockStdio,
      AnsiTerminal: () => MockTerminal(),
    });

    testUsingContext('choose first ephemeral device', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        ephemeralTwo,
      ];

      when(mockStdio.stdinHasTerminal).thenReturn(true);
      when(globals.terminal.promptForCharInput(<String>['0', '1'],
        logger: globals.logger,
        prompt: globals.userMessages.flutterChooseOne)
      ).thenAnswer((Invocation invocation) async => '0');

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        ephemeralOne
      ]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Stdio: () => mockStdio,
      AnsiTerminal: () => MockTerminal(),
    });

    testUsingContext('choose second ephemeral device', () async {
      final List<Device> devices = <Device>[
        ephemeralOne,
        ephemeralTwo,
      ];

      when(mockStdio.stdinHasTerminal).thenReturn(true);
      when(globals.terminal.promptForCharInput(<String>['0', '1'],
        logger: globals.logger,
        prompt: globals.userMessages.flutterChooseOne)
      ).thenAnswer((Invocation invocation) async => '1');

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        ephemeralTwo
      ]);
    }, overrides: <Type, Generator>{
      Stdio: () => mockStdio,
      AnsiTerminal: () => MockTerminal(),
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

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

      when(mockStdio.stdinHasTerminal).thenReturn(true);
      when(globals.terminal.promptForCharInput(<String>['0', '1', '2', '3'],
        logger: globals.logger,
        prompt: globals.userMessages.flutterChooseOne)
      ).thenAnswer((Invocation invocation) async => '2');

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        nonEphemeralOne
      ]);
    }, overrides: <Type, Generator>{
      Stdio: () => mockStdio,
      AnsiTerminal: () => MockTerminal(),
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('Removes a single unsupported device', () async {
      final List<Device> devices = <Device>[
        unsupported,
      ];

      final DeviceManager deviceManager = TestDeviceManager(devices);
      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

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

      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('Removes unsupported devices from --all', () async {
      final List<Device> devices = <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
        unsupported,
      ];
      final DeviceManager deviceManager = TestDeviceManager(devices);
      deviceManager.specifiedDeviceId = 'all';

      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        nonEphemeralOne,
        nonEphemeralTwo,
      ]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });

    testUsingContext('uses DeviceManager.isDeviceSupportedForProject instead of device.isSupportedForProject', () async {
      final List<Device> devices = <Device>[
        unsupported,
      ];
      final TestDeviceManager deviceManager = TestDeviceManager(devices);
      deviceManager.isAlwaysSupportedOverride = true;

      final List<Device> filtered = await deviceManager.findTargetDevices(FlutterProject.current());

      expect(filtered, <Device>[
        unsupported,
      ]);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(),
      Cache: () => cache,
    });
  });
  group('ForwardedPort', () {
    group('dispose()', () {
      testUsingContext('does not throw exception if no process is present', () {
        final ForwardedPort forwardedPort = ForwardedPort(123, 456);
        expect(forwardedPort.context, isNull);
        forwardedPort.dispose();
      });

      testUsingContext('kills process if process was available', () {
        final MockProcess mockProcess = MockProcess();
        final ForwardedPort forwardedPort = ForwardedPort.withContext(123, 456, mockProcess);
        forwardedPort.dispose();
        expect(forwardedPort.context, isNotNull);
        verify(mockProcess.kill());
      });
    });
  });

  group('JSON encode devices', () {
    testUsingContext('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, dartFlags: null)), '');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo')), '--foo');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '', nullAssertions: true)), '--null_assertions');
    expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo', nullAssertions: true)), '--foo,--null_assertions');
  });
}

class TestDeviceManager extends DeviceManager {
    TestDeviceManager(List<Device> allDevices, {
    bool testLongPollingDeviceDiscovery = false,
    bool testThrowingDeviceDiscovery = false,
  }) {
    _fakeDeviceDiscoverer = FakePollingDeviceDiscovery();
    _deviceDiscoverers = <DeviceDiscovery>[
      if (testLongPollingDeviceDiscovery)
        LongPollingDeviceDiscovery(),
      if (testThrowingDeviceDiscovery)
        ThrowingPollingDeviceDiscovery(),
      _fakeDeviceDiscoverer,
    ];
    resetDevices(allDevices);
  }
  @override
  List<DeviceDiscovery> get deviceDiscoverers => _deviceDiscoverers;
  List<DeviceDiscovery> _deviceDiscoverers;
  FakePollingDeviceDiscovery _fakeDeviceDiscoverer;

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

  bool isAlwaysSupportedOverride;

  @override
  bool isDeviceSupportedForProject(Device device, FlutterProject flutterProject) {
    if (isAlwaysSupportedOverride != null) {
      return isAlwaysSupportedOverride;
    }
    return super.isDeviceSupportedForProject(device, flutterProject);
  }
}

class MockProcess extends Mock implements Process {}
class MockTerminal extends Mock implements AnsiTerminal {}
class MockStdio extends Mock implements Stdio {}
class MockCache extends Mock implements Cache {}
