// Copyright 2020 The Fuchsia 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';

import 'package:args/args.dart';
import 'package:fxtest/fxtest.dart';
import 'package:fxutils/fxutils.dart';
import 'package:pedantic/pedantic.dart';

/// Translator for command line arguments into [FuchsiaTestCommand] primitives.
class FuchsiaTestCommandCli {
  /// Callable that prints help/usage information for when the user passes
  /// invalid arguments or "--help".
  final Function(ArgParser) usage;

  /// Fully-hydrated object containing answers to every runtime question.
  /// Derivable from the set of raw arguments passed in by the user.
  late final TestsConfig testsConfig;

  /// The underlying class which does all the work.
  FuchsiaTestCommand? _cmd;

  /// Used to create any new directories needed to house test output / artifacts.
  final DirectoryBuilder? directoryBuilder;

  final IFxEnv fxEnv;

  FuchsiaTestCommandCli(
    List<String> rawArgs, {
    required this.usage,
    required this.fxEnv,
    this.directoryBuilder,
  }) {
    testsConfig = TestsConfig.fromRawArgs(
      rawArgs: rawArgs,
      // When running real tests, turn on logging. Passing `--no-log` explicitly
      // will still override this.
      // The `null` value is not a falsy indicator - it is because `--log` is a
      // flag and thus does not accept a value.
      defaultRawArgs: {'--log': null},
      fxEnv: fxEnv,
    );
  }

  Future<bool> preRunChecks(
    Function(Object) stdoutWriter, {
    ProcessLauncher? processLauncher,
  }) async {
    if (testsConfig.testArguments.parsedArgs['help']) {
      usage(fxTestArgParser);
      return false;
    }
    if (testsConfig.testArguments.parsedArgs['printtests']) {
      processLauncher ??= ProcessLauncher();
      ProcessResult result = await processLauncher.run('cat', ['tests.json'],
          workingDirectory: fxEnv.outputDir);
      stdoutWriter(result.stdout);
      return false;
    }

    // This command uses extensive fx re-entry, so it's good to make sure fx
    // is actually located where we expect
    final fxFile = File(testsConfig.fxEnv.fx);
    if (!fxFile.existsSync()) {
      throw MissingFxException();
    }

    return true;
  }

  Future<void> run() async {
    _cmd = createCommand();

    // Without waiting, start the command.
    unawaited(
      // But register a listener for when it completes, which resolves the
      // stdout future.
      _cmd!.runTestSuite(TestsManifestReader()).then((_) {
        // Once the actual command finishes without problems, close the stdout.
        _cmd!.dispose();
      }),
    );

    // Register a listener for when the `stdout` closes.
    try {
      await Future.wait(
        _cmd!.outputFormatters.map((var f) => f.stdOutClosedFuture),
        eagerError: true,
      );
    } on Exception {
      if (exitCode == 0) {
        rethrow;
      } else {
        throw OutputClosedException(exitCode);
      }
    }
  }

  FuchsiaTestCommand createCommand() => FuchsiaTestCommand.fromConfig(
        testsConfig,
        directoryBuilder: directoryBuilder,
        testRunnerBuilder: (TestsConfig testsConfig) => SymbolizingTestRunner(
          fx: testsConfig.fxEnv.fx,
        ),
      );

  Future<void> terminateEarly() async {
    _cmd?.emitEvent(AllTestsCompleted());
  }

  Future<void> cleanUp() async {
    await _cmd?.cleanUp();
  }
}
