// 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 '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;

  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<Object>(<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, {
    @required bool headless,
    String chromeBinary,
    @required String browserName,
    bool androidEmulator,
    int driverPort,
    List<String> browserDimension,
    String profileMemory,
  }) async {
    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, chromeBinary),
        spec: async_io.WebDriverSpec.Auto
      );
    } 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);
      int x;
      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] and
/// [chromeBinary].
@visibleForTesting
Map<String, dynamic> getDesiredCapabilities(Browser browser, bool headless, [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'
          ],
          'perfLoggingPrefs': <String, String>{
            'traceCategories':
            'devtools.timeline,'
                'v8,blink.console,benchmark,blink,'
                'blink.user_timing'
          }
        },
      };
      break;
    case Browser.firefox:
      return <String, dynamic>{
        'acceptInsecureCerts': true,
        'browserName': 'firefox',
        'moz:firefoxOptions' : <String, dynamic>{
          'args': <String>[
            if (headless) '-headless'
          ],
          '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'}
        }
      };
      break;
    case Browser.edge:
      return <String, dynamic>{
        'acceptInsecureCerts': true,
        'browserName': 'edge',
      };
      break;
    case Browser.safari:
      return <String, dynamic>{
        'browserName': 'safari',
      };
      break;
    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']
        },
      };
  }
  throw UnsupportedError('Browser $browser not supported.'); // dead code; remove with null safety migration
}

/// 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');
}
