// 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.

// @dart = 2.8

import 'package:meta/meta.dart';
import 'package:process/process.dart';

import '../application_package.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/version.dart';
import '../build_info.dart';
import '../device.dart';
import '../device_port_forwarder.dart';
import '../features.dart';
import '../project.dart';
import 'chrome.dart';

class WebApplicationPackage extends ApplicationPackage {
  WebApplicationPackage(this.flutterProject) : super(id: flutterProject.manifest.appName);

  final FlutterProject flutterProject;

  @override
  String get name => flutterProject.manifest.appName;

  /// The location of the web source assets.
  Directory get webSourcePath => flutterProject.directory.childDirectory('web');
}

/// A web device that supports a chromium browser.
abstract class ChromiumDevice extends Device {
  ChromiumDevice({
    @required String name,
    @required this.chromeLauncher,
    @required FileSystem fileSystem,
    @required Logger logger,
  }) : _fileSystem = fileSystem,
       _logger = logger,
       super(
         name,
         category: Category.web,
         platformType: PlatformType.web,
         ephemeral: false,
       );

  final ChromiumLauncher chromeLauncher;

  final FileSystem _fileSystem;
  final Logger _logger;

  /// The active chrome instance.
  Chromium _chrome;

  // TODO(jonahwilliams): this is technically false, but requires some refactoring
  // to allow hot mode restart only devices.
  @override
  bool get supportsHotReload => true;

  @override
  bool get supportsHotRestart => true;

  @override
  bool get supportsStartPaused => true;

  @override
  bool get supportsFlutterExit => false;

  @override
  bool get supportsScreenshot => false;

  @override
  bool supportsRuntimeMode(BuildMode buildMode) => buildMode != BuildMode.jitRelease;

  @override
  void clearLogs() { }

  DeviceLogReader _logReader;

  @override
  DeviceLogReader getLogReader({
    ApplicationPackage app,
    bool includePastLogs = false,
  }) {
    return _logReader ??= NoOpDeviceLogReader(app?.name);
  }

  @override
  Future<bool> installApp(
    ApplicationPackage app, {
    String userIdentifier,
  }) async => true;

  @override
  Future<bool> isAppInstalled(
    ApplicationPackage app, {
    String userIdentifier,
  }) async => true;

  @override
  Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true;

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

  @override
  Future<String> get emulatorId async => null;

  @override
  bool isSupported() =>  chromeLauncher.canFindExecutable();

  @override
  DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();

  @override
  Future<LaunchResult> startApp(
    covariant WebApplicationPackage package, {
    String mainPath,
    String route,
    DebuggingOptions debuggingOptions,
    Map<String, Object> platformArgs,
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String userIdentifier,
  }) async {
    // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
    // for the web initialization and server logic.
    final String url = platformArgs['uri'] as String;
    final bool launchChrome = platformArgs['no-launch-chrome'] != true;
    if (launchChrome) {
      _chrome = await chromeLauncher.launch(
        url,
        cacheDir: _fileSystem.currentDirectory
            .childDirectory('.dart_tool')
            .childDirectory('chrome-device'),
        headless: debuggingOptions.webRunHeadless,
        debugPort: debuggingOptions.webBrowserDebugPort,
      );
    }
    _logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': launchChrome});
    return LaunchResult.succeeded(observatoryUri: url != null ? Uri.parse(url): null);
  }

  @override
  Future<bool> stopApp(
    ApplicationPackage app, {
    String userIdentifier,
  }) async {
    await _chrome?.close();
    return true;
  }

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

  @override
  Future<bool> uninstallApp(
    ApplicationPackage app, {
    String userIdentifier,
  }) async => true;

  @override
  bool isSupportedForProject(FlutterProject flutterProject) {
    return flutterProject.web.existsSync();
  }

  @override
  Future<void> dispose() async {
    _logReader?.dispose();
    await portForwarder?.dispose();
  }
}

/// The Google Chrome browser based on Chromium.
class GoogleChromeDevice extends ChromiumDevice {
  GoogleChromeDevice({
    @required Platform platform,
    @required ProcessManager processManager,
    @required ChromiumLauncher chromiumLauncher,
    @required Logger logger,
    @required FileSystem fileSystem,
  }) : _platform = platform,
       _processManager = processManager,
       super(
          name: 'chrome',
          chromeLauncher: chromiumLauncher,
          logger: logger,
          fileSystem: fileSystem,
       );

  final Platform _platform;
  final ProcessManager _processManager;

  @override
  String get name => 'Chrome';

  @override
  Future<String> get sdkNameAndVersion async => _sdkNameAndVersion ??= await _computeSdkNameAndVersion();

  String _sdkNameAndVersion;
  Future<String> _computeSdkNameAndVersion() async {
    if (!isSupported()) {
      return 'unknown';
    }
    // See https://bugs.chromium.org/p/chromium/issues/detail?id=158372
    String version = 'unknown';
    if (_platform.isWindows) {
      if (_processManager.canRun('reg')) {
        final ProcessResult result = await _processManager.run(<String>[
          r'reg', 'query', r'HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon', '/v', 'version',
        ]);
        if (result.exitCode == 0) {
          final List<String> parts = (result.stdout as String).split(RegExp(r'\s+'));
          if (parts.length > 2) {
            version = 'Google Chrome ' + parts[parts.length - 2];
          }
        }
      }
    } else {
      final String chrome = chromeLauncher.findExecutable();
      final ProcessResult result = await _processManager.run(<String>[
        chrome,
        '--version',
      ]);
      if (result.exitCode == 0) {
        version = result.stdout as String;
      }
    }
    return version.trim();
  }
}

/// The Microsoft Edge browser based on Chromium.
class MicrosoftEdgeDevice extends ChromiumDevice {
  MicrosoftEdgeDevice({
    @required ChromiumLauncher chromiumLauncher,
    @required Logger logger,
    @required FileSystem fileSystem,
    @required ProcessManager processManager,
  }) : _processManager = processManager,
       super(
         name: 'edge',
         chromeLauncher: chromiumLauncher,
         logger: logger,
         fileSystem: fileSystem,
       );

  final ProcessManager _processManager;

  // The first version of Edge with chromium support.
  static const int _kFirstChromiumEdgeMajorVersion = 79;

  @override
  String get name => 'Edge';

  Future<bool> _meetsVersionConstraint() async {
    final String rawVersion = (await sdkNameAndVersion).replaceFirst('Microsoft Edge ', '');
    final Version version = Version.parse(rawVersion);
    if (version == null) {
      return false;
    }
    return version.major >= _kFirstChromiumEdgeMajorVersion;
  }

  @override
  Future<String> get sdkNameAndVersion async => _sdkNameAndVersion ??= await _getSdkNameAndVersion();
  String _sdkNameAndVersion;
  Future<String> _getSdkNameAndVersion() async {
    if (_processManager.canRun('reg')) {
      final ProcessResult result = await _processManager.run(<String>[
        r'reg', 'query', r'HKEY_CURRENT_USER\Software\Microsoft\Edge\BLBeacon', '/v', 'version',
      ]);
      if (result.exitCode == 0) {
        final List<String> parts = (result.stdout as String).split(RegExp(r'\s+'));
        if (parts.length > 2) {
          return 'Microsoft Edge ' + parts[parts.length - 2];
        }
      }
    }
    // Return a non-null string so that the tool can validate the version
    // does not meet the constraint above in _meetsVersionConstraint.
    return '';
  }
}

class WebDevices extends PollingDeviceDiscovery {
  WebDevices({
    @required FileSystem fileSystem,
    @required Logger logger,
    @required Platform platform,
    @required ProcessManager processManager,
    @required FeatureFlags featureFlags,
  }) : _featureFlags = featureFlags,
       super('Chrome') {
    final OperatingSystemUtils operatingSystemUtils = OperatingSystemUtils(
      fileSystem: fileSystem,
      platform: platform,
      logger: logger,
      processManager: processManager,
    );
    _chromeDevice = GoogleChromeDevice(
      fileSystem: fileSystem,
      logger: logger,
      platform: platform,
      processManager: processManager,
      chromiumLauncher: ChromiumLauncher(
        browserFinder: findChromeExecutable,
        fileSystem: fileSystem,
        platform: platform,
        processManager: processManager,
        operatingSystemUtils: operatingSystemUtils,
        logger: logger,
      ),
    );
    if (platform.isWindows) {
      _edgeDevice = MicrosoftEdgeDevice(
        chromiumLauncher: ChromiumLauncher(
          browserFinder: findEdgeExecutable,
          fileSystem: fileSystem,
          platform: platform,
          processManager: processManager,
          operatingSystemUtils: operatingSystemUtils,
          logger: logger,
        ),
        processManager: processManager,
        logger: logger,
        fileSystem: fileSystem,
      );
    }
    _webServerDevice = WebServerDevice(
      logger: logger,
    );
  }

  GoogleChromeDevice _chromeDevice;
  WebServerDevice _webServerDevice;
  MicrosoftEdgeDevice _edgeDevice;
  final FeatureFlags _featureFlags;

  @override
  bool get canListAnything => featureFlags.isWebEnabled;

  @override
  Future<List<Device>> pollingGetDevices({ Duration timeout }) async {
    if (!_featureFlags.isWebEnabled) {
      return <Device>[];
    }
    return <Device>[
      if (WebServerDevice.showWebServerDevice)
        _webServerDevice,
      if (_chromeDevice.isSupported())
        _chromeDevice,
      if (await _edgeDevice?._meetsVersionConstraint() ?? false)
        _edgeDevice,
    ];
  }

  @override
  bool get supportsPlatform =>  _featureFlags.isWebEnabled;
}

@visibleForTesting
String parseVersionForWindows(String input) {
  return input.split(RegExp(r'\w')).last;
}


/// A special device type to allow serving for arbitrary browsers.
class WebServerDevice extends Device {
  WebServerDevice({
    @required Logger logger,
  }) : _logger = logger,
       super(
         'web-server',
          platformType: PlatformType.web,
          category: Category.web,
          ephemeral: false,
       );

  static const String kWebServerDeviceId = 'web-server';
  static bool showWebServerDevice = false;

  final Logger _logger;

  @override
  void clearLogs() { }

  @override
  Future<String> get emulatorId => null;

  DeviceLogReader _logReader;

  @override
  DeviceLogReader getLogReader({
    ApplicationPackage app,
    bool includePastLogs = false,
  }) {
    return _logReader ??= NoOpDeviceLogReader(app?.name);
  }

  @override
  Future<bool> installApp(
    ApplicationPackage app, {
    String userIdentifier,
  }) async => true;

  @override
  Future<bool> isAppInstalled(
    ApplicationPackage app, {
    String userIdentifier,
  }) async => true;

  @override
  Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true;

  @override
  bool get supportsFlutterExit => false;

  @override
  bool supportsRuntimeMode(BuildMode buildMode) => buildMode != BuildMode.jitRelease;

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

  @override
  bool isSupported() => true;

  @override
  bool isSupportedForProject(FlutterProject flutterProject) {
    return flutterProject.web.existsSync();
  }

  @override
  String get name => 'Web Server';

  @override
  DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();

  @override
  Future<String> get sdkNameAndVersion async => 'Flutter Tools';

  @override
  Future<LaunchResult> startApp(ApplicationPackage package, {
    String mainPath,
    String route,
    DebuggingOptions debuggingOptions,
    Map<String, Object> platformArgs,
    bool prebuiltApplication = false,
    bool ipv6 = false,
    String userIdentifier,
  }) async {
    final String url = platformArgs['uri'] as String;
    if (debuggingOptions.startPaused) {
      _logger.printStatus('Waiting for connection from Dart debug extension at $url', emphasis: true);
    } else {
      _logger.printStatus('$mainPath is being served at $url', emphasis: true);
    }
    _logger.printStatus(
      'The web-server device requires the Dart Debug Chrome extension for debugging. '
      'Consider using the Chrome or Edge devices for an improved development workflow.'
    );
    _logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': false});
    return LaunchResult.succeeded(observatoryUri: url != null ? Uri.parse(url): null);
  }

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

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

  @override
  Future<bool> uninstallApp(
    ApplicationPackage app, {
    String userIdentifier,
  }) async {
    return true;
  }

  @override
  Future<void> dispose() async {
    _logReader?.dispose();
    await portForwarder?.dispose();
  }
}
