// 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:file/memory.dart';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/commands/daemon.dart';
import 'package:flutter_tools/src/daemon.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/proxied_devices/devices.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:test/fake.dart';

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

void main() {
  Daemon? daemon;
  late NotifyingLogger notifyingLogger;
  late BufferLogger bufferLogger;
  late FakeAndroidDevice fakeDevice;

  late FakeApplicationPackageFactory applicationPackageFactory;
  late MemoryFileSystem memoryFileSystem;
  late FakeProcessManager fakeProcessManager;

  group('ProxiedDevices', () {
    late DaemonConnection serverDaemonConnection;
    late DaemonConnection clientDaemonConnection;
    setUp(() {
      bufferLogger = BufferLogger.test();
      notifyingLogger = NotifyingLogger(verbose: false, parent: bufferLogger);
      final FakeDaemonStreams serverDaemonStreams = FakeDaemonStreams();
      serverDaemonConnection = DaemonConnection(
        daemonStreams: serverDaemonStreams,
        logger: bufferLogger,
      );
      final FakeDaemonStreams clientDaemonStreams = FakeDaemonStreams();
      clientDaemonConnection = DaemonConnection(
        daemonStreams: clientDaemonStreams,
        logger: bufferLogger,
      );

      serverDaemonStreams.inputs.addStream(clientDaemonStreams.outputs.stream);
      clientDaemonStreams.inputs.addStream(serverDaemonStreams.outputs.stream);

      applicationPackageFactory = FakeApplicationPackageFactory();
      memoryFileSystem = MemoryFileSystem();
      fakeProcessManager = FakeProcessManager.empty();
    });

    tearDown(() async {
      if (daemon != null) {
        return daemon!.shutdown();
      }
      notifyingLogger.dispose();
      await serverDaemonConnection.dispose();
      await clientDaemonConnection.dispose();
    });

    testUsingContext('can list devices', () async {
      daemon = Daemon(
        serverDaemonConnection,
        notifyingLogger: notifyingLogger,
      );
      fakeDevice = FakeAndroidDevice();
      final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
      daemon!.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(fakeDevice);

      final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);

      final List<Device> devices = await proxiedDevices.discoverDevices();
      expect(devices, hasLength(1));
      final Device device = devices[0];
      expect(device.id, fakeDevice.id);
      expect(device.name, 'Proxied ${fakeDevice.name}');
      expect(await device.targetPlatform, await fakeDevice.targetPlatform);
      expect(await device.isLocalEmulator, await fakeDevice.isLocalEmulator);
    });

    testUsingContext('calls supportsRuntimeMode', () async {
      daemon = Daemon(
        serverDaemonConnection,
        notifyingLogger: notifyingLogger,
      );
      fakeDevice = FakeAndroidDevice();
      final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
      daemon!.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(fakeDevice);

      final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);

      final List<Device> devices = await proxiedDevices.devices;
      expect(devices, hasLength(1));
      final Device device = devices[0];
      final bool supportsRuntimeMode = await device.supportsRuntimeMode(BuildMode.release);
      expect(fakeDevice.supportsRuntimeModeCalledBuildMode, BuildMode.release);
      expect(supportsRuntimeMode, true);
    });

    testUsingContext('redirects logs', () async {
      daemon = Daemon(
        serverDaemonConnection,
        notifyingLogger: notifyingLogger,
      );
      fakeDevice = FakeAndroidDevice();
      final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
      daemon!.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(fakeDevice);

      final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);

      final FakeDeviceLogReader fakeLogReader = FakeDeviceLogReader();
      fakeDevice.logReader = fakeLogReader;

      final List<Device> devices = await proxiedDevices.devices;
      expect(devices, hasLength(1));
      final Device device = devices[0];
      final DeviceLogReader logReader = await device.getLogReader();
      fakeLogReader.logLinesController.add('Some log line');

      final String receivedLogLine = await logReader.logLines.first;
      expect(receivedLogLine, 'Some log line');

      // Now try to stop the log reader
      expect(fakeLogReader.disposeCalled, false);
      logReader.dispose();
      await pumpEventQueue();
      expect(fakeLogReader.disposeCalled, true);
    });
    testUsingContext('starts and stops app', () async {
      daemon = Daemon(
        serverDaemonConnection,
        notifyingLogger: notifyingLogger,
      );
      fakeDevice = FakeAndroidDevice();
      final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
      daemon!.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(fakeDevice);

      final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);
      final FakePrebuiltApplicationPackage prebuiltApplicationPackage = FakePrebuiltApplicationPackage();
      final File dummyApplicationBinary = memoryFileSystem.file('/directory/dummy_file');
      dummyApplicationBinary.parent.createSync();
      dummyApplicationBinary.writeAsStringSync('dummy content');
      prebuiltApplicationPackage.applicationPackage = dummyApplicationBinary;

      final List<Device> devices = await proxiedDevices.devices;
      expect(devices, hasLength(1));
      final Device device = devices[0];

      // Now try to start the app
      final FakeApplicationPackage applicationPackage = FakeApplicationPackage();
      applicationPackageFactory.applicationPackage = applicationPackage;

      final Uri observatoryUri = Uri.parse('http://127.0.0.1:12345/observatory');
      fakeDevice.launchResult = LaunchResult.succeeded(observatoryUri: observatoryUri);

      final LaunchResult launchResult = await device.startApp(
        prebuiltApplicationPackage,
        debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
      );

      expect(launchResult.started, true);
      // The returned observatoryUri was a forwarded port, so we cannot compare them directly.
      expect(launchResult.observatoryUri!.path, observatoryUri.path);

      expect(applicationPackageFactory.applicationBinaryRequested!.readAsStringSync(), 'dummy content');
      expect(applicationPackageFactory.platformRequested, TargetPlatform.android_arm);

      expect(fakeDevice.startAppPackage, applicationPackage);

      // Now try to stop the app
      final bool stopAppResult = await device.stopApp(prebuiltApplicationPackage);
      expect(fakeDevice.stopAppPackage, applicationPackage);
      expect(stopAppResult, true);
    }, overrides: <Type, Generator>{
      ApplicationPackageFactory: () => applicationPackageFactory,
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeProcessManager,
    });

    testUsingContext('takes screenshot', () async {
      daemon = Daemon(
        serverDaemonConnection,
        notifyingLogger: notifyingLogger,
      );
      fakeDevice = FakeAndroidDevice();
      final FakePollingDeviceDiscovery discoverer = FakePollingDeviceDiscovery();
      daemon!.deviceDomain.addDeviceDiscoverer(discoverer);
      discoverer.addDevice(fakeDevice);

      final ProxiedDevices proxiedDevices = ProxiedDevices(clientDaemonConnection, logger: bufferLogger);

      final List<Device> devices = await proxiedDevices.devices;
      expect(devices, hasLength(1));
      final Device device = devices[0];

      final List<int> screenshot = <int>[1,2,3,4,5];
      fakeDevice.screenshot = screenshot;

      final File screenshotOutputFile = memoryFileSystem.file('screenshot_file');
      await device.takeScreenshot(screenshotOutputFile);

      expect(await screenshotOutputFile.readAsBytes(), screenshot);
    }, overrides: <Type, Generator>{
      FileSystem: () => memoryFileSystem,
      ProcessManager: () => fakeProcessManager,
    });
  });
}

class FakeDaemonStreams implements DaemonStreams {
  final StreamController<DaemonMessage> inputs = StreamController<DaemonMessage>();
  final StreamController<DaemonMessage> outputs = StreamController<DaemonMessage>();

  @override
  Stream<DaemonMessage> get inputStream {
    return inputs.stream;
  }

  @override
  void send(Map<String, dynamic> message, [ List<int>? binary ]) {
    outputs.add(DaemonMessage(message, binary != null ? Stream<List<int>>.value(binary) : null));
  }

  @override
  Future<void> dispose() async {
    await inputs.close();
    // In some tests, outputs have no listeners. We don't wait for outputs to close.
    unawaited(outputs.close());
  }
}

// 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 FakeAndroidDevice extends Fake implements AndroidDevice {
  @override
  final String id = 'device';

  @override
  final String name = 'device';

  @override
  Future<String> get emulatorId async => 'device';

  @override
  Future<TargetPlatform> get targetPlatform async => TargetPlatform.android_arm;

  @override
  Future<bool> get isLocalEmulator async => false;

  @override
  final Category category = Category.mobile;

  @override
  final PlatformType platformType = PlatformType.android;

  @override
  final bool ephemeral = false;

  @override
  Future<String> get sdkNameAndVersion async => 'Android 12';

  @override
  bool get supportsHotReload => true;

  @override
  bool get supportsHotRestart => true;

  @override
  bool get supportsScreenshot => true;

  @override
  bool get supportsFastStart => true;

  @override
  bool get supportsFlutterExit => true;

  @override
  Future<bool> get supportsHardwareRendering async => true;

  @override
  bool get supportsStartPaused => true;

  BuildMode? supportsRuntimeModeCalledBuildMode;
  @override
  Future<bool> supportsRuntimeMode(BuildMode buildMode) async {
    supportsRuntimeModeCalledBuildMode = buildMode;
    return true;
  }

  late DeviceLogReader logReader;
  @override
  FutureOr<DeviceLogReader> getLogReader({
    covariant ApplicationPackage? app,
    bool includePastLogs = false,
  }) => logReader;

  ApplicationPackage? startAppPackage;
  late LaunchResult launchResult;
  @override
  Future<LaunchResult> startApp(
    ApplicationPackage package, {
    String? mainPath,
    String? route,
    DebuggingOptions? debuggingOptions,
    Map<String, Object?> platformArgs = const <String, Object>{},
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String? userIdentifier,
  }) async {
    startAppPackage = package;
    return launchResult;
  }

  ApplicationPackage? stopAppPackage;
  @override
  Future<bool> stopApp(
    ApplicationPackage app, {
    String? userIdentifier,
  }) async {
    stopAppPackage = app;
    return true;
  }

  late List<int> screenshot;
  @override
  Future<void> takeScreenshot(File outputFile) {
    return outputFile.writeAsBytes(screenshot);
  }
}

class FakeDeviceLogReader implements DeviceLogReader {
  final StreamController<String> logLinesController = StreamController<String>();
  bool disposeCalled = false;

  @override
  int? appPid;

  @override
  FlutterVmService? connectedVMService;

  @override
  void dispose() {
    disposeCalled = true;
  }

  @override
  Stream<String> get logLines => logLinesController.stream;

  @override
  String get name => 'device';

}

class FakeApplicationPackageFactory implements ApplicationPackageFactory {
  TargetPlatform? platformRequested;
  File? applicationBinaryRequested;
  ApplicationPackage? applicationPackage;

  @override
  Future<ApplicationPackage?> getPackageForPlatform(TargetPlatform platform, {BuildInfo? buildInfo, File? applicationBinary}) async {
    platformRequested = platform;
    applicationBinaryRequested = applicationBinary;
    return applicationPackage;
  }
}

class FakeApplicationPackage extends Fake implements ApplicationPackage {}

class FakePrebuiltApplicationPackage extends Fake implements PrebuiltApplicationPackage {
  @override
  late File applicationPackage;
}
