// 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 'package:file/src/interface/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/net.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/drive/web_driver_service.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/web/web_runner.dart';
import 'package:test/fake.dart';
import 'package:webdriver/sync_io.dart' as sync_io;

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

void main() {
  testWithoutContext('getDesiredCapabilities Chrome with headless on', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'acceptInsecureCerts': true,
      'browserName': 'chrome',
      'goog:loggingPrefs': <String, String>{
        sync_io.LogType.browser: 'INFO',
        sync_io.LogType.performance: 'ALL',
      },
      'chromeOptions': <String, dynamic>{
        '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',
          '--headless',
        ],
        'perfLoggingPrefs': <String, String>{
          'traceCategories':
          'devtools.timeline,'
          'v8,blink.console,benchmark,blink,'
          'blink.user_timing',
        },
      },
    };

    expect(getDesiredCapabilities(Browser.chrome, true), expected);
  });

  testWithoutContext('getDesiredCapabilities Chrome with headless off', () {
    const String chromeBinary = 'random-binary';
    final Map<String, dynamic> expected = <String, dynamic>{
      'acceptInsecureCerts': true,
      'browserName': 'chrome',
      'goog:loggingPrefs': <String, String>{
        sync_io.LogType.browser: 'INFO',
        sync_io.LogType.performance: 'ALL',
      },
      'chromeOptions': <String, dynamic>{
        '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',
        ],
        'perfLoggingPrefs': <String, String>{
          'traceCategories':
          'devtools.timeline,'
          'v8,blink.console,benchmark,blink,'
          'blink.user_timing',
        },
      },
    };

    expect(getDesiredCapabilities(Browser.chrome, false, chromeBinary), expected);

  });

  testWithoutContext('getDesiredCapabilities Firefox with headless on', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'acceptInsecureCerts': true,
      'browserName': 'firefox',
      'moz:firefoxOptions' : <String, dynamic>{
        'args': <String>['-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'},
      },
    };

    expect(getDesiredCapabilities(Browser.firefox, true), expected);
  });

  testWithoutContext('getDesiredCapabilities Firefox with headless off', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'acceptInsecureCerts': true,
      'browserName': 'firefox',
      'moz:firefoxOptions' : <String, dynamic>{
        'args': <String>[],
        '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'},
      },
    };

    expect(getDesiredCapabilities(Browser.firefox, false), expected);
  });

  testWithoutContext('getDesiredCapabilities Edge', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'acceptInsecureCerts': true,
      'browserName': 'edge',
    };

    expect(getDesiredCapabilities(Browser.edge, false), expected);
  });

  testWithoutContext('getDesiredCapabilities macOS Safari', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'browserName': 'safari',
    };

    expect(getDesiredCapabilities(Browser.safari, false), expected);
  });

  testWithoutContext('getDesiredCapabilities iOS Safari', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'platformName': 'ios',
      'browserName': 'safari',
      'safari:useSimulator': true,
    };

    expect(getDesiredCapabilities(Browser.iosSafari, false), expected);
  });

  testWithoutContext('getDesiredCapabilities android chrome', () {
    final Map<String, dynamic> expected = <String, dynamic>{
      'browserName': 'chrome',
      'platformName': 'android',
      'goog:chromeOptions': <String, dynamic>{
        'androidPackage': 'com.android.chrome',
        'args': <String>['--disable-fullscreen'],
      },
    };

    expect(getDesiredCapabilities(Browser.androidChrome, false), expected);
  });

  testUsingContext('WebDriverService starts and stops an app', () async {
    final WebDriverService service = setUpDriverService();
    final FakeDevice device = FakeDevice();
    await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
    await service.stop();
    expect(FakeResidentRunner.instance.callLog, <String>[
      'run',
      'exitApp',
      'cleanupAtFinish',
    ]);
  }, overrides: <Type, Generator>{
    WebRunnerFactory: () => FakeWebRunnerFactory(),
  });

  testUsingContext('WebDriverService forwards exception when run future fails before app starts', () async {
    final WebDriverService service = setUpDriverService();
    final Device device = FakeDevice();
    await expectLater(
      service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true),
      throwsA('This is a test error'),
    );
  }, overrides: <Type, Generator>{
    WebRunnerFactory: () => FakeWebRunnerFactory(
      doResolveToError: true,
    ),
  });
}

class FakeWebRunnerFactory implements WebRunnerFactory {
  FakeWebRunnerFactory({
    this.doResolveToError = false,
  });

  final bool doResolveToError;

  @override
  ResidentRunner createWebRunner(FlutterDevice device, {String target, bool stayResident, FlutterProject flutterProject, bool ipv6, DebuggingOptions debuggingOptions, UrlTunneller urlTunneller, Logger logger, FileSystem fileSystem, SystemClock systemClock, Usage usage, bool machine = false}) {
    expect(stayResident, isTrue);
    return FakeResidentRunner(
      doResolveToError: doResolveToError,
    );
  }
}

class FakeResidentRunner extends Fake implements ResidentRunner {
  FakeResidentRunner({
    this.doResolveToError,
  }) {
    instance = this;
  }

  static FakeResidentRunner instance;

  final bool doResolveToError;
  final Completer<int> _exitCompleter = Completer<int>();
  final List<String> callLog = <String>[];

  @override
  Uri get uri => Uri();

  @override
  Future<int> run({
    Completer<DebugConnectionInfo> connectionInfoCompleter,
    Completer<void> appStartedCompleter,
    bool enableDevTools = false,
    String route,
  }) async {
    callLog.add('run');

    if (doResolveToError) {
      return Future<int>.error('This is a test error');
    }

    appStartedCompleter.complete();
    // Emulate stayResident by completing after exitApp is called.
    return _exitCompleter.future;
  }

  @override
  Future<void> exitApp() async {
    callLog.add('exitApp');
    _exitCompleter.complete();
  }

  @override
  Future<void> cleanupAtFinish() async {
    callLog.add('cleanupAtFinish');
  }
}

WebDriverService setUpDriverService() {
  final BufferLogger logger = BufferLogger.test();
  return WebDriverService(
    logger: logger,
    processUtils: ProcessUtils(
      logger: logger,
      processManager: FakeProcessManager.any(),
    ),
    dartSdkPath: 'dart',
  );
}

// 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 FakeDevice extends Fake implements Device {
  @override
  final PlatformType platformType = PlatformType.web;

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