// 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.

import 'dart:async';
import 'dart:convert';
import 'dart:core' hide print;
import 'dart:io' as io;

import 'package:path/path.dart' as path;

import 'utils.dart';

/// Runs the `executable` and returns standard output as a stream of lines.
///
/// The returned stream reaches its end immediately after the command exits.
///
/// If `expectNonZeroExit` is false and the process exits with a non-zero exit
/// code fails the test immediately by exiting the test process with exit code
/// 1.
Stream<String> runAndGetStdout(String executable, List<String> arguments, {
  String workingDirectory,
  Map<String, String> environment,
  bool expectNonZeroExit = false,
  bool expectNoTests = false,
}) async* {
  final StreamController<String> output = StreamController<String>();
  final Future<CommandResult> command = runCommand(
    executable,
    arguments,
    workingDirectory: workingDirectory,
    environment: environment,
    expectNonZeroExit: expectNonZeroExit,
    expectNoTests: expectNoTests,
    // Capture the output so it's not printed to the console by default.
    outputMode: OutputMode.capture,
    outputListener: (String line, io.Process process) {
      output.add(line);
    },
  );

  // Close the stream controller after the command is complete. Otherwise,
  // the yield* will never finish.
  command.whenComplete(output.close);

  yield* output.stream;
}

/// Represents a running process launched using [startCommand].
class Command {
  Command._(this.process, this._time, this._savedStdout, this._savedStderr);

  /// The raw process that was launched for this command.
  final io.Process process;

  final Stopwatch _time;
  final Future<List<List<int>>> _savedStdout;
  final Future<List<List<int>>> _savedStderr;

  /// Evaluates when the [process] exits.
  ///
  /// Returns the result of running the command.
  Future<CommandResult> get onExit async {
    final int exitCode = await process.exitCode;
    _time.stop();

    // Saved output is null when OutputMode.print is used.
    final String flattenedStdout = _savedStdout != null ? _flattenToString(await _savedStdout) : null;
    final String flattenedStderr = _savedStderr != null ? _flattenToString(await _savedStderr) : null;
    return CommandResult._(exitCode, _time.elapsed, flattenedStdout, flattenedStderr);
  }
}

/// The result of running a command using [startCommand] and [runCommand];
class CommandResult {
  CommandResult._(this.exitCode, this.elapsedTime, this.flattenedStdout, this.flattenedStderr);

  /// The exit code of the process.
  final int exitCode;

  /// The amount of time it took the process to complete.
  final Duration elapsedTime;

  /// Standard output decoded as a string using UTF8 decoder.
  final String flattenedStdout;

  /// Standard error output decoded as a string using UTF8 decoder.
  final String flattenedStderr;
}

/// Starts the `executable` and returns a command object representing the
/// running process.
///
/// `outputListener` is called for every line of standard output from the
/// process, and is given the [Process] object. This can be used to interrupt
/// an indefinitely running process, for example, by waiting until the process
/// emits certain output.
///
/// `outputMode` controls where the standard output from the command process
/// goes. See [OutputMode].
Future<Command> startCommand(String executable, List<String> arguments, {
  String workingDirectory,
  Map<String, String> environment,
  OutputMode outputMode = OutputMode.print,
  bool Function(String) removeLine,
  void Function(String, io.Process) outputListener,
}) async {
  final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
  final String relativeWorkingDir = path.relative(workingDirectory ?? io.Directory.current.path);
  printProgress('RUNNING', relativeWorkingDir, commandDescription);

  final Stopwatch time = Stopwatch()..start();
  final io.Process process = await io.Process.start(executable, arguments,
    workingDirectory: workingDirectory,
    environment: environment,
  );

  Future<List<List<int>>> savedStdout = Future<List<List<int>>>.value(<List<int>>[]);
  Future<List<List<int>>> savedStderr = Future<List<List<int>>>.value(<List<int>>[]);
  final Stream<List<int>> stdoutSource = process.stdout
    .transform<String>(const Utf8Decoder())
    .transform(const LineSplitter())
    .where((String line) => removeLine == null || !removeLine(line))
    .map((String line) {
      final String formattedLine = '$line\n';
      if (outputListener != null) {
        outputListener(formattedLine, process);
      }
      return formattedLine;
    })
    .transform(const Utf8Encoder());
  switch (outputMode) {
    case OutputMode.print:
      stdoutSource.listen((List<int> output) {
        io.stdout.add(output);
        savedStdout.then((List<List<int>> list) => list.add(output));
      });
      process.stderr.listen((List<int> output) {
        io.stderr.add(output);
        savedStdout.then((List<List<int>> list) => list.add(output));
      });
      break;
    case OutputMode.capture:
      savedStdout = stdoutSource.toList();
      savedStderr = process.stderr.toList();
      break;
  }

  return Command._(process, time, savedStdout, savedStderr);
}

/// Runs the `executable` and waits until the process exits.
///
/// If the process exits with a non-zero exit code, exits this process with
/// exit code 1, unless `expectNonZeroExit` is set to true.
///
/// `outputListener` is called for every line of standard output from the
/// process, and is given the [Process] object. This can be used to interrupt
/// an indefinitely running process, for example, by waiting until the process
/// emits certain output.
///
/// Returns the result of the finished process, or null if `skip` is true.
///
/// `outputMode` controls where the standard output from the command process
/// goes. See [OutputMode].
Future<CommandResult> runCommand(String executable, List<String> arguments, {
  String workingDirectory,
  Map<String, String> environment,
  bool expectNonZeroExit = false,
  bool expectNoTests = false,
  int expectedExitCode,
  String failureMessage,
  OutputMode outputMode = OutputMode.print,
  bool skip = false,
  bool Function(String) removeLine,
  void Function(String, io.Process) outputListener,
}) async {
  final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
  final String relativeWorkingDir = path.relative(workingDirectory ?? io.Directory.current.path);
  if (skip) {
    printProgress('SKIPPING', relativeWorkingDir, commandDescription);
    return null;
  }

  final Command command = await startCommand(executable, arguments,
    workingDirectory: workingDirectory,
    environment: environment,
    outputMode: outputMode,
    removeLine: removeLine,
    outputListener: outputListener,
  );

  final CommandResult result = await command.onExit;

  // Currently, the test infrastructure fails if it doesn't find any tests to
  // run, but in the case of tests tagged as "no-shuffle", there might either be
  // none that can be shuffled, or none that shouldn't be shuffled, and since
  // we're running it twice to get all the tests in either category, it
  // shouldn't fail if no tests are run.
  //
  // TODO(gspencergoog): This is a workaround until
  // https://github.com/dart-lang/test/issues/1546 is addressed. Remove the
  // workaround (parsing the test output) when/if that issue is fixed.
  final bool skipErrorExit = expectNoTests &&
      result != null &&
      result.flattenedStdout != null &&
      result.flattenedStdout.trimRight().endsWith('No tests ran.');

  if (!skipErrorExit && ((result.exitCode == 0) == expectNonZeroExit || (expectedExitCode != null && result.exitCode != expectedExitCode))) {
    // Print the output when we get unexpected results (unless output was
    // printed already).
    switch (outputMode) {
      case OutputMode.print:
        break;
      case OutputMode.capture:
        io.stdout.writeln(result.flattenedStdout);
        io.stderr.writeln(result.flattenedStderr);
        break;
    }
    exitWithError(<String>[
      if (failureMessage != null)
        failureMessage
      else
        '${bold}ERROR: ${red}Last command exited with ${result.exitCode} (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset',
      '${bold}Command: $green$commandDescription$reset',
      '${bold}Relative working directory: $cyan$relativeWorkingDir$reset',
    ]);
  }
  print('$clock ELAPSED TIME: ${prettyPrintDuration(result.elapsedTime)} for $green$commandDescription$reset in $cyan$relativeWorkingDir$reset');
  return result;
}

/// Flattens a nested list of UTF-8 code units into a single string.
String _flattenToString(List<List<int>> chunks) =>
  utf8.decode(chunks.expand<int>((List<int> ints) => ints).toList());

/// Specifies what to do with the command output from [runCommand] and [startCommand].
enum OutputMode {
  /// Forwards standard output and standard error streams to the test process'
  /// respective standard streams.
  ///
  /// Use this mode if all you want is print the output of the command to the
  /// console. The output is no longer available after the process exits.
  print,

  /// Saves standard output and standard error streams in memory.
  ///
  /// Captured output can be retrieved from the [CommandResult] object.
  ///
  /// Use this mode in tests that need to inspect the output of a command, or
  /// when the output should not be printed to console.
  capture,
}
