// 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/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/web/chrome.dart';
import 'package:flutter_tools/src/web/web_device.dart';

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

void main() {
  testWithoutContext('No web devices listed if feature is disabled', () async {
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager:  FakeProcessManager.any(),
    );

    expect(await webDevices.pollingGetDevices(), isEmpty);
  });

  testWithoutContext('GoogleChromeDevice defaults', () async {
    final TestChromiumLauncher launcher = TestChromiumLauncher();

    final GoogleChromeDevice chromeDevice = GoogleChromeDevice(
      chromiumLauncher: launcher,
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(),
      processManager: FakeProcessManager.any(),
    );

    expect(chromeDevice.name, 'Chrome');
    expect(chromeDevice.id, 'chrome');
    expect(chromeDevice.supportsHotReload, true);
    expect(chromeDevice.supportsHotRestart, true);
    expect(chromeDevice.supportsStartPaused, true);
    expect(chromeDevice.supportsFlutterExit, false);
    expect(chromeDevice.supportsScreenshot, false);
    expect(await chromeDevice.isLocalEmulator, false);
    expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(await chromeDevice.portForwarder!.forward(1), 1);

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

  testWithoutContext('MicrosoftEdge defaults', () async {
    final TestChromiumLauncher launcher = TestChromiumLauncher();

    final MicrosoftEdgeDevice chromeDevice = MicrosoftEdgeDevice(
      chromiumLauncher: launcher,
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
    );

    expect(chromeDevice.name, 'Edge');
    expect(chromeDevice.id, 'edge');
    expect(chromeDevice.supportsHotReload, true);
    expect(chromeDevice.supportsHotRestart, true);
    expect(chromeDevice.supportsStartPaused, true);
    expect(chromeDevice.supportsFlutterExit, false);
    expect(chromeDevice.supportsScreenshot, false);
    expect(await chromeDevice.isLocalEmulator, false);
    expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(await chromeDevice.portForwarder!.forward(1), 1);

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

  testWithoutContext('Server defaults', () async {
    final WebServerDevice device = WebServerDevice(
      logger: BufferLogger.test(),
    );

    expect(device.name, 'Web Server');
    expect(device.id, 'web-server');
    expect(device.supportsHotReload, true);
    expect(device.supportsHotRestart, true);
    expect(device.supportsStartPaused, true);
    expect(device.supportsFlutterExit, false);
    expect(device.supportsScreenshot, false);
    expect(await device.isLocalEmulator, false);
    expect(device.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(device.getLogReader(), isA<NoOpDeviceLogReader>());
    expect(await device.portForwarder!.forward(1), 1);

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

  testWithoutContext('Chrome device is listed when Chrome can be run', () async {
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager:  FakeProcessManager.any(),
    );

    expect(await webDevices.pollingGetDevices(),
      contains(isA<GoogleChromeDevice>()));
  });

  testWithoutContext('Has well known device ids chrome, edge, and web-server', () async {
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager:  FakeProcessManager.any(),
    );

    expect(webDevices.wellKnownIds, <String>['chrome', 'web-server', 'edge']);
  });

  testWithoutContext('Chrome device is not listed when Chrome cannot be run', () async {
    final FakeProcessManager processManager = FakeProcessManager.empty();
    processManager.excludedExecutables = <String>{kLinuxExecutable};
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager: processManager,
    );

    expect(await webDevices.pollingGetDevices(),
      isNot(contains(isA<GoogleChromeDevice>())));
  });

  testWithoutContext('Web Server device is listed if enabled via showWebServerDevice', () async {
    WebServerDevice.showWebServerDevice = true;
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager: FakeProcessManager.any(),
    );

    expect(await webDevices.pollingGetDevices(),
      contains(isA<WebServerDevice>()));
  });

  testWithoutContext('Web Server device is not listed if disabled via showWebServerDevice', () async {
    WebServerDevice.showWebServerDevice = false;
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager: FakeProcessManager.any(),
    );

    expect(await webDevices.pollingGetDevices(),
      isNot(contains(isA<WebServerDevice>())));
  });

  testWithoutContext('Chrome invokes version command on non-Windows platforms', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          kLinuxExecutable,
          '--version',
        ],
        stdout: 'ABC'
      )
    ]);
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager: processManager,
    );


    final GoogleChromeDevice chromeDevice = (await webDevices.pollingGetDevices())
      .whereType<GoogleChromeDevice>().first;

    expect(chromeDevice.isSupported(), true);
    expect(await chromeDevice.sdkNameAndVersion, 'ABC');

    // Verify caching works correctly.
    expect(await chromeDevice.sdkNameAndVersion, 'ABC');
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Chrome and Edge version check invokes registry query on windows.', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'reg',
          'query',
          r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon',
          '/v',
          'version',
        ],
        stdout: r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon\ version REG_SZ 83.0.478.44 ',
      ),
      const FakeCommand(
        command: <String>[
          'reg',
          'query',
          r'HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon',
          '/v',
          'version',
        ],
        stdout: r'HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon\ version REG_SZ 74.0.0 A',
      )
    ]);
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        operatingSystem: 'windows',
        environment: <String, String>{}
      ),
      processManager: processManager,
    );


    final GoogleChromeDevice chromeDevice = (await webDevices.pollingGetDevices())
      .whereType<GoogleChromeDevice>().first;

    expect(chromeDevice.isSupported(), true);
    expect(await chromeDevice.sdkNameAndVersion, 'Google Chrome 74.0.0');

    // Verify caching works correctly.
    expect(await chromeDevice.sdkNameAndVersion, 'Google Chrome 74.0.0');
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Chrome and Edge version check handles missing registry on Windows', () async {
    final FakeProcessManager processManager = FakeProcessManager.empty();
    processManager.excludedExecutables.add('reg');

    final Platform platform = FakePlatform(
        operatingSystem: 'windows', environment: <String, String>{});
    final ChromiumLauncher chromeLauncher = ChromiumLauncher(
      fileSystem: MemoryFileSystem.test(),
      platform: platform,
      processManager: processManager,
      operatingSystemUtils: FakeOperatingSystemUtils(),
      browserFinder: findChromeExecutable,
      logger: BufferLogger.test(),
    );
    final MicrosoftEdgeDevice edgeDevice = MicrosoftEdgeDevice(
      chromiumLauncher: chromeLauncher,
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      processManager: processManager,
    );

    expect(edgeDevice.isSupported(), true);
    expect(await edgeDevice.sdkNameAndVersion, '');

    final GoogleChromeDevice chromeDevice = GoogleChromeDevice(
      chromiumLauncher: chromeLauncher,
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      processManager: processManager,
      platform: platform,
    );

    expect(chromeDevice.isSupported(), true);
    expect(await chromeDevice.sdkNameAndVersion, 'unknown');
  });

  testWithoutContext('Edge is not supported on versions less than 73', () async {
    final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>[
          'reg',
          'query',
          r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon',
          '/v',
          'version',
        ],
        stdout: r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon\ version REG_SZ 72.0.478.44 ',
      ),
    ]);
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        operatingSystem: 'windows',
        environment: <String, String>{}
      ),
      processManager: processManager,
    );

    expect((await webDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);
  });

  testWithoutContext('Edge is not support on non-windows platform', () async {
    final WebDevices webDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        environment: <String, String>{}
      ),
      processManager: FakeProcessManager.empty(),
    );

    expect((await webDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);

    final WebDevices macosWebDevices = WebDevices(
      featureFlags: TestFeatureFlags(isWebEnabled: true),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      platform: FakePlatform(
        operatingSystem: 'macos',
        environment: <String, String>{}
      ),
      processManager: FakeProcessManager.empty(),
    );

    expect((await macosWebDevices.pollingGetDevices()).whereType<MicrosoftEdgeDevice>(), isEmpty);
  });
}

/// A test implementation of the [ChromiumLauncher] that launches a fixed instance.
class TestChromiumLauncher implements ChromiumLauncher {
  TestChromiumLauncher();

  bool _hasInstance = false;
  void setInstance(Chromium chromium) {
    _hasInstance = true;
    currentCompleter.complete(chromium);
  }

  @override
  Completer<Chromium> currentCompleter = Completer<Chromium>();

  @override
  bool canFindExecutable() {
    return true;
  }

  @override
  Future<Chromium> get connectedInstance => currentCompleter.future;

  @override
  String findExecutable() {
    return 'chrome';
  }

  @override
  bool get hasChromeInstance => _hasInstance;

  @override
  Future<Chromium> launch(String url, {bool headless = false, int? debugPort, bool skipCheck = false, Directory? cacheDir}) async {
    return currentCompleter.future;
  }
}
