// 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:fxutils/fxutils.dart';
import 'package:meta/meta.dart';

/// Re-entry helper for running other fx subcommands from within any subcommand
/// written in Dart.
///
/// [Fx] instances are source-tree aware (via [RootLocator]), and launch
/// processes via a helper [startProcess].
///
/// Usage:
/// ```dart
/// final fx = Fx();
///
/// // Run prepared commands
/// final deviceName = await fx.getDeviceName();
///
/// // Run custom, specific commands.
/// // This runs `fx some-command`.
/// final output = await fx.getSubCommandOutput('some-command');
/// ```
class Fx {
  final IFxEnv fxEnv;
  final ProcessLauncher _processLauncher;
  Fx({
    @required this.fxEnv,
    StartProcess processStarter,
  })  : assert(fxEnv != null),
        _processLauncher = ProcessLauncher(processStarter: processStarter);

  factory Fx.mock(Process process, IFxEnv fxEnv) => Fx(
        processStarter: returnGivenProcess(process),
        fxEnv: fxEnv,
      );

  Future<String> getDeviceName() async {
    return await getSubCommandOutput('get-device');
  }

  Future<bool> isPackageServerRunning() async {
    try {
      await getSubCommandOutput('is-package-server-running');
    } on FailedProcessException {
      return false;
    }
    return true;
  }

  Future<bool> updateIfInBase(
    List<String> testNames, {
    int batchSize = 50,
  }) async {
    final testNamesIterator = ListIterator<String>.from(testNames);
    while (testNamesIterator.isNotEmpty) {
      final result = await runFxSubCommand(
        'update-if-in-base',
        args: testNamesIterator.take(batchSize),
      );
      if (result.exitCode != 0) {
        return false;
      }
    }
    return true;
  }

  /// Helper which invokes a command and returns the response.
  ///
  /// Intentionally offers no realtime access to output, or to the stderr. This
  /// is meant to simplify the task of getting output from an fx subcommand.
  Future<String> getSubCommandOutput(
    /// fx subcommand to execute. For example, "device-name", "status", etc.
    String cmd, {

    /// Optional list of arguments to pass to the subcommand.
    List<String> args,

    /// Accepted exit codes. Unexpected exit codes will throw a
    /// [FailedProcessException]. Set this to [null] to never throw an
    /// exception.
    List<int> allowedExitCodes = const [0],

    /// Convenience flag to remove trailing whitespace from the command, since
    /// that is unlikely to be desired.
    bool shouldTrimTrailing = true,
  }) async {
    final processResult = await runFxSubCommand(
      cmd,
      args: args,
    );
    if (allowedExitCodes != null &&
        !allowedExitCodes.contains(processResult.exitCode)) {
      final fullCommand = [fxEnv.fx, cmd, ...?args];
      throw FailedProcessException(
        command: fullCommand,
        exitCode: processResult.exitCode,
        stdout: processResult.stdout,
        stderr: processResult.stderr,
      );
    }
    return shouldTrimTrailing
        // ignore: avoid_as
        ? (processResult.stdout as String).trimRight()
        : processResult.stdout;
  }

  /// Basic wrapper around running an fx subcommand which exposes all necessary
  /// controls to the caller.
  Future<ProcessResult> runFxSubCommand(
    /// Specific `fx` subcommand to execute.
    String cmd, {

    /// Argument and flags for the subcommand. Optional.
    List<String> args,

    /// I/O mode of the spawned process. Defaults to
    /// [ProcessStartMode.inheritStdio] if unset and if [stdoutSink] and
    /// [stderrSink] are null.
    ProcessStartMode mode = ProcessStartMode.normal,

    // /// Handler for converting raw bytes into readable strings
    SystemEncoding encoding = systemEncoding,
  }) async {
    return _processLauncher.run(
      fxEnv.fx,
      [cmd, ...?args],
      mode: mode,
      outputEncoding: encoding,
    );
  }
}
