// 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;
// TODO(yjbanov): remove hacks when this is fixed:
//                https://github.com/dart-lang/test/issues/1521
import 'package:test_api/src/backend/group.dart' as hack;
import 'package:test_api/src/backend/live_test.dart' as hack;
import 'package:test_api/src/backend/runtime.dart' as hack;
import 'package:test_core/src/executable.dart' as test;
import 'package:test_core/src/runner/configuration/reporters.dart' as hack;
import 'package:test_core/src/runner/engine.dart' as hack;
import 'package:test_core/src/runner/hack_register_platform.dart' as hack;
import 'package:test_core/src/runner/reporter.dart' as hack;

import '../browser.dart';
import '../environment.dart';
import '../exceptions.dart';
import '../pipeline.dart';
import '../test_platform.dart';
import '../utils.dart';

// Maximum number of tests that run concurrently.
const int _testConcurrency = int.fromEnvironment('FELT_TEST_CONCURRENCY', defaultValue: 10);

/// Runs web tests.
///
/// Assumes the artifacts from [CompileTestsStep] are available, either from
/// running it prior to this step locally, or by having the build graph copy
/// them from another bot.
class RunTestsStep implements PipelineStep {
  RunTestsStep({
    required this.browserEnvironment,
    required this.isDebug,
    required this.doUpdateScreenshotGoldens,
    this.testFiles,
  });

  final BrowserEnvironment browserEnvironment;
  final List<FilePath>? testFiles;
  final bool isDebug;
  final bool doUpdateScreenshotGoldens;

  /// Global list of shards that failed.
  ///
  /// This is used to make sure that when there's a test failure anywhere we
  /// exit with a non-zero exit code.
  ///
  /// Shards must never be removed from this list, only added.
  List<String> failedShards = <String>[];

  /// Whether all test shards succeeded.
  bool get allShardsPassed => failedShards.isEmpty;

  @override
  String get description => 'run_tests';

  @override
  bool get isSafeToInterrupt => true;

  @override
  Future<void> interrupt() async {}

  @override
  Future<void> run() async {
    _copyTestFontsIntoWebUi();
    await _prepareTestResultsDirectory();
    await browserEnvironment.prepareEnvironment();

    final List<FilePath> testFiles = this.testFiles ?? findAllTests();

    // Separate screenshot tests from unit-tests. Screenshot tests must run
    // one at a time. Otherwise, they will end up screenshotting each other.
    // This is not an issue for unit-tests.
    final FilePath failureSmokeTestPath = FilePath.fromWebUi(
      'test/golden_tests/golden_failure_smoke_test.dart',
    );
    final List<FilePath> screenshotTestFiles = <FilePath>[];
    final List<FilePath> unitTestFiles = <FilePath>[];

    for (final FilePath testFilePath in testFiles) {
      if (!testFilePath.absolute.endsWith('_test.dart')) {
        // Not a test file at all. Skip.
        continue;
      }
      if (testFilePath == failureSmokeTestPath) {
        // A smoke test that fails on purpose. Skip.
        continue;
      }

      // All files under test/golden_tests are considered golden tests.
      final bool isUnderGoldenTestsDirectory =
          pathlib.split(testFilePath.relativeToWebUi).contains('golden_tests');
      // Any file whose name ends with "_golden_test.dart" is run as a golden test.
      final bool isGoldenTestFile = pathlib
          .basename(testFilePath.relativeToWebUi)
          .endsWith('_golden_test.dart');
      if (isUnderGoldenTestsDirectory || isGoldenTestFile) {
        screenshotTestFiles.add(testFilePath);
      } else {
        unitTestFiles.add(testFilePath);
      }
    }

    // This test returns a non-zero exit code on purpose. Run it separately.
    if (testFiles.contains(failureSmokeTestPath)) {
      await _runTestBatch(
        testFiles: <FilePath>[failureSmokeTestPath],
        browserEnvironment: browserEnvironment,
        concurrency: 1,
        expectFailure: true,
        isDebug: isDebug,
        doUpdateScreenshotGoldens: doUpdateScreenshotGoldens,
      );
    }

    // Run non-screenshot tests with high concurrency.
    if (unitTestFiles.isNotEmpty) {
      await _runTestBatch(
        testFiles: unitTestFiles,
        browserEnvironment: browserEnvironment,
        concurrency: _testConcurrency,
        expectFailure: false,
        isDebug: isDebug,
        doUpdateScreenshotGoldens: doUpdateScreenshotGoldens,
      );
      _checkExitCode('Unit tests');
    }

    // Run screenshot tests one at a time to prevent tests from screenshotting
    // each other.
    if (screenshotTestFiles.isNotEmpty) {
      await _runTestBatch(
        testFiles: screenshotTestFiles,
        browserEnvironment: browserEnvironment,
        concurrency: 1,
        expectFailure: false,
        isDebug: isDebug,
        doUpdateScreenshotGoldens: doUpdateScreenshotGoldens,
      );
      _checkExitCode('Golden tests');
    }

    if (!allShardsPassed) {
      throw ToolExit(_createFailedShardsMessage());
    }
  }

  void _checkExitCode(String shard) {
    if (io.exitCode != 0) {
      failedShards.add(shard);
    }
  }

  String _createFailedShardsMessage() {
    final StringBuffer message = StringBuffer(
      'The following test shards failed:\n',
    );
    for (final String failedShard in failedShards) {
      message.writeln(' - $failedShard');
    }
    return message.toString();
  }
}

Future<void> _prepareTestResultsDirectory() async {
  if (environment.webUiTestResultsDirectory.existsSync()) {
    environment.webUiTestResultsDirectory.deleteSync(recursive: true);
  }
  environment.webUiTestResultsDirectory.createSync(recursive: true);
}

const List<String> _kTestFonts = <String>[
  'ahem.ttf',
  'Roboto-Regular.ttf',
  'NotoNaskhArabic-Regular.ttf',
  'NotoColorEmoji.ttf',
];

void _copyTestFontsIntoWebUi() {
  final String fontsPath = pathlib.join(
    environment.flutterDirectory.path,
    'third_party',
    'txt',
    'third_party',
    'fonts',
  );

  for (final String fontFile in _kTestFonts) {
    final io.File sourceTtf = io.File(pathlib.join(fontsPath, fontFile));
    final String destinationTtfPath =
        pathlib.join(environment.webUiRootDir.path, 'lib', 'assets', fontFile);
    sourceTtf.copySync(destinationTtfPath);
  }
}

/// Runs a batch of tests.
///
/// Unless [expectFailure] is set to false, sets [io.exitCode] to a non-zero
/// value if any tests fail.
Future<void> _runTestBatch({
  required List<FilePath> testFiles,
  required bool isDebug,
  required BrowserEnvironment browserEnvironment,
  required bool doUpdateScreenshotGoldens,
  required int concurrency,
  required bool expectFailure,
}) async {
  final String configurationFilePath = pathlib.join(
    environment.webUiRootDir.path,
    browserEnvironment.packageTestConfigurationYamlFile,
  );
  final List<String> testArgs = <String>[
    ...<String>['-r', 'compact'],
    '--concurrency=$concurrency',
    if (isDebug) '--pause-after-load',
    // Don't pollute logs with output from tests that are expected to fail.
    if (expectFailure)
      '--reporter=name-only',
    '--platform=${browserEnvironment.packageTestRuntime.identifier}',
    '--precompiled=${environment.webUiBuildDir.path}',
    '--configuration=$configurationFilePath',
    '--',
    ...testFiles.map((FilePath f) => f.relativeToWebUi).toList(),
  ];

  if (expectFailure) {
    hack.registerReporter(
      'name-only',
      hack.ReporterDetails(
      'Prints the name of the test, but suppresses all other test output.',
      (_, hack.Engine engine, __) => NameOnlyReporter(engine)),
    );
  }

  hack.registerPlatformPlugin(<hack.Runtime>[
    browserEnvironment.packageTestRuntime,
  ], () {
    return BrowserPlatform.start(
      browserEnvironment: browserEnvironment,
      // It doesn't make sense to update a screenshot for a test that is
      // expected to fail.
      doUpdateScreenshotGoldens: !expectFailure && doUpdateScreenshotGoldens,
    );
  });

  // We want to run tests with `web_ui` as a working directory.
  final dynamic originalCwd = io.Directory.current;
  io.Directory.current = environment.webUiRootDir.path;
  try {
    await test.main(testArgs);
  } finally {
    io.Directory.current = originalCwd;
  }

  if (expectFailure) {
    if (io.exitCode != 0) {
      // It failed, as expected.
      print('Test successfully failed, as expected.');
      io.exitCode = 0;
    } else {
      io.stderr.writeln(
        'Tests ${testFiles.join(', ')} did not fail. Expected failure.',
      );
      io.exitCode = 1;
    }
  }
}

/// Prints the name of the test, but suppresses all other test output.
///
/// This is useful to prevent pollution of logs by tests that are expected to
/// fail.
class NameOnlyReporter implements hack.Reporter {
  NameOnlyReporter(hack.Engine testEngine) {
    testEngine.onTestStarted.listen(_printTestName);
  }

  void _printTestName(hack.LiveTest test) {
    print('Running ${test.groups.map((hack.Group group) => group.name).join(' ')} ${test.individualName}');
  }

  @override
  void pause() {}

  @override
  void resume() {}
}
