// Copyright 2013 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:io' as io;
import 'package:path/path.dart' as pathlib;
import 'package:web_driver_installer/chrome_driver_installer.dart';

import 'chrome_installer.dart';
import 'environment.dart';
import 'exceptions.dart';
import 'common.dart';
import 'utils.dart';

class IntegrationTestsManager {
  final String _browser;

  /// Installation directory for browser's driver.
  ///
  /// Always re-install since driver can change frequently.
  /// It usually changes with each the browser version changes.
  /// A better solution would be installing the browser and the driver at the
  /// same time.
  // TODO(nurhan): https://github.com/flutter/flutter/issues/53179. Partly
  // solved. Remaining local integration tests using the locked Chrome version.
  final io.Directory _browserDriverDir;

  /// This is the parent directory for all drivers.
  ///
  /// This directory is saved to [temporaryDirectories] and deleted before
  /// tests shutdown.
  final io.Directory _drivers;

  final bool _useSystemFlutter;

  IntegrationTestsManager(this._browser, this._useSystemFlutter)
      : this._browserDriverDir = io.Directory(pathlib.join(
            environment.webUiDartToolDir.path,
            'drivers',
            _browser,
            '${_browser}driver-${io.Platform.operatingSystem.toString()}')),
        this._drivers = io.Directory(
            pathlib.join(environment.webUiDartToolDir.path, 'drivers'));

  Future<bool> runTests() async {
    if (_browser != 'chrome') {
      print('WARNING: integration tests are only supported on chrome for now');
      return false;
    } else {
      if (!isLuci) {
        // LUCI installs driver from CIPD, so we skip installing it on LUCI.
        await _prepareDriver();
      } else {
        await _verifyDriverForLUCI();
      }
      await _startDriver(_browserDriverDir.path);
      // TODO(nurhan): https://github.com/flutter/flutter/issues/52987
      return await _runTests();
    }
  }

  Future<void> _runPubGet(String workingDirectory) async {
    if (!_useSystemFlutter) {
      await _cloneFlutterRepo();
      await _enableWeb(workingDirectory);
    }
    await runFlutter(workingDirectory, <String>['pub', 'get'],
        useSystemFlutter: _useSystemFlutter);
  }

  /// Clone flutter repository, use the youngest commit older than the engine
  /// commit.
  ///
  /// Use engine/src/flutter/.dart_tools to clone the Flutter repo.
  /// TODO(nurhan): Use git pull instead if repo exists.
  Future<void> _cloneFlutterRepo() async {
    // Delete directory if exists.
    if (environment.engineDartToolDir.existsSync()) {
      environment.engineDartToolDir.deleteSync(recursive: true);
    }
    environment.engineDartToolDir.createSync();

    final int exitCode = await runProcess(
      environment.cloneFlutterScript.path,
      <String>[
        environment.engineDartToolDir.path,
      ],
      workingDirectory: environment.webUiRootDir.path,
    );

    if (exitCode != 0) {
      throw ToolException('ERROR: Failed to clone flutter repo. Exited with '
          'exit code $exitCode');
    }
  }

  Future<void> _enableWeb(String workingDirectory) async {
    await runFlutter(workingDirectory, <String>['config', '--enable-web'],
        useSystemFlutter: _useSystemFlutter);
  }

  /// Driver should already exist on LUCI as a CIPD package.
  ///
  /// Throw an error if directory does not exists.
  void _verifyDriverForLUCI() {
    if (!_browserDriverDir.existsSync()) {
      throw StateError('Failed to locate Chrome driver on LUCI on path:'
          '${_browserDriverDir.path}');
    }
  }

  void _startDriver(String workingDirectory) async {
    await startProcess('./chromedriver/chromedriver', ['--port=4444'],
        workingDirectory: workingDirectory);
    print('INFO: Driver started');
  }

  void _prepareDriver() async {
    if (_browserDriverDir.existsSync()) {
      _browserDriverDir.deleteSync(recursive: true);
    }

    _browserDriverDir.createSync(recursive: true);
    temporaryDirectories.add(_drivers);

    io.Directory temp = io.Directory.current;
    io.Directory.current = _browserDriverDir;

    // TODO(nurhan): https://github.com/flutter/flutter/issues/53179
    final String chromeDriverVersion = await queryChromeDriverVersion();
    ChromeDriverInstaller chromeDriverInstaller =
        ChromeDriverInstaller.withVersion(chromeDriverVersion);
    await chromeDriverInstaller.install(alwaysInstall: true);
    io.Directory.current = temp;
  }

  /// Runs all the web tests under e2e_tests/web.
  Future<bool> _runTests() async {
    // Only list the files under e2e_tests/web.
    final List<io.FileSystemEntity> entities =
        environment.integrationTestsDir.listSync(followLinks: false);

    bool allTestsPassed = true;
    for (io.FileSystemEntity e in entities) {
      // The tests should be under this directories.
      if (e is io.Directory) {
        allTestsPassed = allTestsPassed && await _validateAndRunTests(e);
      }
    }
    return allTestsPassed;
  }

  /// Run tests in a single directory under: e2e_tests/web.
  ///
  /// Run `flutter pub get` as the first step.
  ///
  /// Validate the directory before running the tests. Each directory is
  /// expected to be a test project which includes a `pubspec.yaml` file
  /// and a `test_driver` directory.
  Future<bool> _validateAndRunTests(io.Directory directory) async {
    _validateTestDirectory(directory);
    await _runPubGet(directory.path);
    final bool testResults = await _runTestsInDirectory(directory);
    return testResults;
  }

  Future<bool> _runTestsInDirectory(io.Directory directory) async {
    final io.Directory testDirectory =
        io.Directory(pathlib.join(directory.path, 'test_driver'));
    final List<io.File> entities = testDirectory
        .listSync(followLinks: false)
        .whereType<io.File>()
        .toList();

    final List<String> e2eTestsToRun = List<String>();
    final List<String> blackList =
        blackListsMap[getBlackListMapKey(_browser)] ?? <String>[];

    // The following loops over the contents of the directory and saves an
    // expected driver file name for each e2e test assuming any dart file
    // not ending with `_test.dart` is an e2e test.
    // Other files are not considered since developers can add files such as
    // README.
    for (io.File f in entities) {
      final String basename = pathlib.basename(f.path);
      if (!basename.contains('_test.dart') && basename.endsWith('.dart')) {
        // Do not add the basename if it is in the blacklist.
        if (!blackList.contains(basename)) {
          e2eTestsToRun.add(basename);
        } else {
          print('INFO: Test $basename is skipped since it is blacklisted for '
              '${getBlackListMapKey(_browser)}');
        }
      }
    }

    print(
        'INFO: In project ${directory} ${e2eTestsToRun.length} tests to run.');

    int numberOfPassedTests = 0;
    int numberOfFailedTests = 0;
    for (String fileName in e2eTestsToRun) {
      final bool testResults =
          await _runTestsInProfileMode(directory, fileName);
      if (testResults) {
        numberOfPassedTests++;
      } else {
        numberOfFailedTests++;
      }
    }
    final int numberOfTestsRun = numberOfPassedTests + numberOfFailedTests;

    print('INFO: ${numberOfTestsRun} tests run. ${numberOfPassedTests} passed '
        'and ${numberOfFailedTests} failed.');
    return numberOfFailedTests == 0;
  }

  Future<bool> _runTestsInProfileMode(
      io.Directory directory, String testName) async {
    final String executable =
        _useSystemFlutter ? 'flutter' : environment.flutterCommand.path;
    final int exitCode = await runProcess(
      executable,
      <String>[
        'drive',
        '--target=test_driver/${testName}',
        '-d',
        'web-server',
        '--profile',
        '--browser-name=$_browser',
        if (isLuci) '--chrome-binary=${preinstalledChromeExecutable()}',
        if (isLuci) '--headless',
        '--local-engine=host_debug_unopt',
      ],
      workingDirectory: directory.path,
    );

    if (exitCode != 0) {
      String statementToRun = 'flutter drive '
          '--target=test_driver/${testName} -d web-server --profile '
          '--browser-name=$_browser --local-engine=host_debug_unopt';
      if (isLuci) {
        statementToRun = '$statementToRun --chrome-binary='
            '${preinstalledChromeExecutable()}';
      }
      io.stderr
          .writeln('ERROR: Failed to run test. Exited with exit code $exitCode'
              '. Statement to run $testName locally use the following '
              'command:\n\n$statementToRun');
      return false;
    } else {
      return true;
    }
  }

  /// Validate the directory has a `pubspec.yaml` file and a `test_driver`
  /// directory.
  ///
  /// Also check the validity of files under `test_driver` directory calling
  /// [_checkE2ETestsValidity] method.
  void _validateTestDirectory(io.Directory directory) {
    final List<io.FileSystemEntity> entities =
        directory.listSync(followLinks: false);

    // Whether the project has the pubspec.yaml file.
    bool pubSpecFound = false;
    // The test directory 'test_driver'.
    io.Directory testDirectory = null;

    for (io.FileSystemEntity e in entities) {
      // The tests should be under this directories.
      final String baseName = pathlib.basename(e.path);
      if (e is io.Directory && baseName == 'test_driver') {
        testDirectory = e;
      }
      if (e is io.File && baseName == 'pubspec.yaml') {
        pubSpecFound = true;
      }
    }
    if (!pubSpecFound) {
      throw StateError('ERROR: pubspec.yaml file not found in the test project '
          'in the directory ${directory.path}.');
    }
    if (testDirectory == null) {
      throw StateError(
          'ERROR: test_driver folder not found in the test project.'
          'in the directory ${directory.path}.');
    } else {
      _checkE2ETestsValidity(testDirectory);
    }
  }

  /// Checks if each e2e test file in the directory has a driver test
  /// file to run it.
  ///
  /// Prints informative message to the developer if an error has found.
  /// For each e2e test which has name {name}.dart there will be a driver
  /// file which drives it. The driver file should be named:
  /// {name}_test.dart
  void _checkE2ETestsValidity(io.Directory testDirectory) {
    final Iterable<io.Directory> directories =
        testDirectory.listSync(followLinks: false).whereType<io.Directory>();

    if (directories.length > 0) {
      throw StateError('${testDirectory.path} directory should not contain '
          'any sub-directories');
    }

    final Iterable<io.File> entities =
        testDirectory.listSync(followLinks: false).whereType<io.File>();

    final Set<String> expectedDriverFileNames = Set<String>();
    final Set<String> foundDriverFileNames = Set<String>();
    int numberOfTests = 0;

    // The following loops over the contents of the directory and saves an
    // expected driver file name for each e2e test assuming any file
    // not ending with `_test.dart` is an e2e test.
    for (io.File f in entities) {
      final String basename = pathlib.basename(f.path);
      if (basename.contains('_test.dart')) {
        // First remove this from expectedSet if not there add to the foundSet.
        if (!expectedDriverFileNames.remove(basename)) {
          foundDriverFileNames.add(basename);
        }
      } else if (basename.contains('.dart')) {
        // Only run on dart files.
        final String e2efileName = pathlib.basenameWithoutExtension(f.path);
        final String expectedDriverName = '${e2efileName}_test.dart';
        numberOfTests++;
        // First remove this from foundSet if not there add to the expectedSet.
        if (!foundDriverFileNames.remove(expectedDriverName)) {
          expectedDriverFileNames.add(expectedDriverName);
        }
      }
    }

    if (numberOfTests == 0) {
      throw StateError(
          'WARNING: No tests to run in this directory ${testDirectory.path}');
    }

    // TODO(nurhan): In order to reduce the work required from team members,
    // remove the need for driver file, by using the same template file.
    // Some driver files are missing.
    if (expectedDriverFileNames.length > 0) {
      for (String expectedDriverName in expectedDriverFileNames) {
        print('ERROR: Test driver file named has ${expectedDriverName} '
            'not found under directory ${testDirectory.path}. Stopping the '
            'integration tests. Please add ${expectedDriverName}. Check to '
            'README file on more details on how to setup integration tests.');
      }
      throw StateError('Error in test files. Check the logs for '
          'further instructions');
    }
  }
}

/// Prepares a key for the [blackList] map.
///
/// Uses the browser name and the operating system name.
String getBlackListMapKey(String browser) =>
    '${browser}-${io.Platform.operatingSystem}';

/// Tests that should be skipped run for a specific platform-browser
/// combination.
///
/// These tests might be failing or might have been implemented for a specific
/// configuration.
///
/// For example a mobile browser only tests will be added to blacklist for
/// `chrome-linux`, `safari-macos` and `chrome-macos`.
///
/// Note that integration tests are only running on chrome for now.
const Map<String, List<String>> blackListsMap = <String, List<String>>{
  'chrome-linux': [
    'target_platform_ios_e2e.dart',
    'target_platform_macos_e2e.dart',
  ],
  'chrome-macos': [
    'target_platform_ios_e2e.dart',
    'target_platform_android_e2e.dart',
  ],
};
