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

import 'package:file/file.dart';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:webdriver/async_io.dart' as async_io;

import '../base/common.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/process.dart';
import '../build_info.dart';
import '../convert.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../resident_runner.dart';
import '../web/web_runner.dart';
import 'drive_service.dart';

/// An implementation of the driver service for web debug and release applications.
class WebDriverService extends DriverService {
  WebDriverService({
    required ProcessUtils processUtils,
    required String dartSdkPath,
    required Logger logger,
  }) : _processUtils = processUtils,
       _dartSdkPath = dartSdkPath,
       _logger = logger;

  final ProcessUtils _processUtils;
  final String _dartSdkPath;
  final Logger _logger;

  late ResidentRunner _residentRunner;
  Uri? _webUri;

  /// The result of [ResidentRunner.run].
  ///
  /// This is expected to stay `null` throughout the test, as the application
  /// must be running until [stop] is called. If it becomes non-null, it likely
  /// indicates a bug.
  int? _runResult;

  @override
  Future<void> start(
    BuildInfo buildInfo,
    Device device,
    DebuggingOptions debuggingOptions,
    bool ipv6, {
    File? applicationBinary,
    String? route,
    String? userIdentifier,
    String? mainPath,
    Map<String, Object> platformArgs = const <String, Object>{},
  }) async {
    final FlutterDevice flutterDevice = await FlutterDevice.create(
      device,
      target: mainPath,
      buildInfo: buildInfo,
      platform: globals.platform,
    );
    _residentRunner = webRunnerFactory!.createWebRunner(
      flutterDevice,
      target: mainPath,
      ipv6: ipv6,
      debuggingOptions: buildInfo.isRelease ?
        DebuggingOptions.disabled(
          buildInfo,
          port: debuggingOptions.port,
        )
        : DebuggingOptions.enabled(
          buildInfo,
          port: debuggingOptions.port,
          disablePortPublication: debuggingOptions.disablePortPublication,
        ),
      stayResident: true,
      urlTunneller: null,
      flutterProject: FlutterProject.current(),
      fileSystem: globals.fs,
      usage: globals.flutterUsage,
      logger: _logger,
      systemClock: globals.systemClock,
    );
    final Completer<void> appStartedCompleter = Completer<void>.sync();
    final Future<int?> runFuture = _residentRunner.run(
      appStartedCompleter: appStartedCompleter,
      route: route,
    );

    bool isAppStarted = false;
    await Future.any(<Future<Object?>>[
      runFuture.then((int? result) {
        _runResult = result;
        return null;
      }),
      appStartedCompleter.future.then((_) {
        isAppStarted = true;
        return null;
      }),
    ]);

    if (_runResult != null) {
      throw ToolExit(
        'Application exited before the test started. Check web driver logs '
        'for possible application-side errors.'
      );
    }

    if (!isAppStarted) {
      throw ToolExit('Failed to start application');
    }

    _webUri = _residentRunner.uri;

    if (_webUri == null) {
      throw ToolExit('Unable to connect to the app. URL not available.');
    }
  }

  @override
  Future<int> startTest(
    String testFile,
    List<String> arguments,
    Map<String, String> environment,
    PackageConfig packageConfig, {
    bool? headless,
    String? chromeBinary,
    String? browserName,
    bool? androidEmulator,
    int? driverPort,
    List<String> webBrowserFlags = const <String>[],
    List<String>? browserDimension,
    String? profileMemory,
  }) async {
    late async_io.WebDriver webDriver;
    final Browser browser = _browserNameToEnum(browserName);
    try {
      webDriver = await async_io.createDriver(
        uri: Uri.parse('http://localhost:$driverPort/'),
        desired: getDesiredCapabilities(
          browser,
          headless,
          webBrowserFlags: webBrowserFlags,
          chromeBinary: chromeBinary,
        ),
      );
    } on SocketException catch (error) {
      _logger.printTrace('$error');
      throwToolExit(
        'Unable to start a WebDriver session for web testing.\n'
        'Make sure you have the correct WebDriver server (e.g. chromedriver) running at $driverPort.\n'
        'For instructions on how to obtain and run a WebDriver server, see:\n'
        'https://flutter.dev/docs/testing/integration-tests#running-in-a-browser\n'
      );
    }

    final bool isAndroidChrome = browser == Browser.androidChrome;
    // Do not set the window size for android chrome browser.
    if (!isAndroidChrome) {
      assert(browserDimension!.length == 2);
      late int x;
      late int y;
      try {
        x = int.parse(browserDimension![0]);
        y = int.parse(browserDimension[1]);
      } on FormatException catch (ex) {
        throwToolExit('Dimension provided to --browser-dimension is invalid: $ex');
      }
      final async_io.Window window = await webDriver.window;
      await window.setLocation(const math.Point<int>(0, 0));
      await window.setSize(math.Rectangle<int>(0, 0, x, y));
    }
    final int result = await _processUtils.stream(<String>[
      _dartSdkPath,
      ...arguments,
      testFile,
      '-rexpanded',
    ], environment: <String, String>{
      'VM_SERVICE_URL': _webUri.toString(),
      ..._additionalDriverEnvironment(webDriver, browserName, androidEmulator),
      ...environment,
    });
    await webDriver.quit();
    return result;
  }

  @override
  Future<void> stop({File? writeSkslOnExit, String? userIdentifier}) async {
    final bool appDidFinishPrematurely = _runResult != null;
    await _residentRunner.exitApp();
    await _residentRunner.cleanupAtFinish();

    if (appDidFinishPrematurely) {
      throw ToolExit(
        'Application exited before the test finished. Check web driver logs '
        'for possible application-side errors.'
      );
    }
  }

  Map<String, String> _additionalDriverEnvironment(async_io.WebDriver webDriver, String? browserName, bool? androidEmulator) {
    return <String, String>{
      'DRIVER_SESSION_ID': webDriver.id,
      'DRIVER_SESSION_URI': webDriver.uri.toString(),
      'DRIVER_SESSION_SPEC': webDriver.spec.toString(),
      'DRIVER_SESSION_CAPABILITIES': json.encode(webDriver.capabilities),
      'SUPPORT_TIMELINE_ACTION': (_browserNameToEnum(browserName) == Browser.chrome).toString(),
      'FLUTTER_WEB_TEST': 'true',
      'ANDROID_CHROME_ON_EMULATOR': (_browserNameToEnum(browserName) == Browser.androidChrome && androidEmulator!).toString(),
    };
  }

  @override
  Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async {
    throwToolExit('--use-existing-app is not supported with flutter web driver');
  }
}

/// A list of supported browsers.
enum Browser {
  /// Chrome on Android: https://developer.chrome.com/multidevice/android/overview
  androidChrome,
  /// Chrome: https://www.google.com/chrome/
  chrome,
  /// Edge: https://www.microsoft.com/en-us/windows/microsoft-edge
  edge,
  /// Firefox: https://www.mozilla.org/en-US/firefox/
  firefox,
  /// Safari in iOS: https://www.apple.com/safari/
  iosSafari,
  /// Safari in macOS: https://www.apple.com/safari/
  safari,
}

/// Returns desired capabilities for given [browser], [headless], [chromeBinary]
/// and [webBrowserFlags].
@visibleForTesting
Map<String, dynamic> getDesiredCapabilities(
  Browser browser,
  bool? headless, {
  List<String> webBrowserFlags = const <String>[],
  String? chromeBinary,
}) {
  switch (browser) {
    case Browser.chrome:
      return <String, dynamic>{
        'acceptInsecureCerts': true,
        'browserName': 'chrome',
        'goog:loggingPrefs': <String, String>{
          async_io.LogType.browser: 'INFO',
          async_io.LogType.performance: 'ALL',
        },
        'chromeOptions': <String, dynamic>{
          if (chromeBinary != null)
            'binary': chromeBinary,
          'w3c': false,
          'args': <String>[
            '--bwsi',
            '--disable-background-timer-throttling',
            '--disable-default-apps',
            '--disable-extensions',
            '--disable-popup-blocking',
            '--disable-translate',
            '--no-default-browser-check',
            '--no-sandbox',
            '--no-first-run',
            if (headless!) '--headless',
            ...webBrowserFlags,
          ],
          'perfLoggingPrefs': <String, String>{
            'traceCategories':
            'devtools.timeline,'
            'v8,blink.console,benchmark,blink,'
            'blink.user_timing',
          },
        },
      };
    case Browser.firefox:
      return <String, dynamic>{
        'acceptInsecureCerts': true,
        'browserName': 'firefox',
        'moz:firefoxOptions' : <String, dynamic>{
          'args': <String>[
            if (headless!) '-headless',
            ...webBrowserFlags,
          ],
          'prefs': <String, dynamic>{
            'dom.file.createInChild': true,
            'dom.timeout.background_throttling_max_budget': -1,
            'media.autoplay.default': 0,
            'media.gmp-manager.url': '',
            'media.gmp-provider.enabled': false,
            'network.captive-portal-service.enabled': false,
            'security.insecure_field_warning.contextual.enabled': false,
            'test.currentTimeOffsetSeconds': 11491200,
          },
          'log': <String, String>{'level': 'trace'},
        },
      };
    case Browser.edge:
      return <String, dynamic>{
        'acceptInsecureCerts': true,
        'browserName': 'edge',
      };
    case Browser.safari:
      return <String, dynamic>{
        'browserName': 'safari',
      };
    case Browser.iosSafari:
      return <String, dynamic>{
        'platformName': 'ios',
        'browserName': 'safari',
        'safari:useSimulator': true,
      };
    case Browser.androidChrome:
      return <String, dynamic>{
        'browserName': 'chrome',
        'platformName': 'android',
        'goog:chromeOptions': <String, dynamic>{
          'androidPackage': 'com.android.chrome',
          'args': <String>[
            '--disable-fullscreen',
            ...webBrowserFlags,
          ],
        },
      };
  }
}

/// Converts [browserName] string to [Browser]
Browser _browserNameToEnum(String? browserName) {
  switch (browserName) {
    case 'android-chrome': return Browser.androidChrome;
    case 'chrome': return Browser.chrome;
    case 'edge': return Browser.edge;
    case 'firefox': return Browser.firefox;
    case 'ios-safari': return Browser.iosSafari;
    case 'safari': return Browser.safari;
  }
  throw UnsupportedError('Browser $browserName not supported');
}
