// 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:meta/meta.dart';
import 'package:process/process.dart';

import 'logger.dart';
import 'operation_result.dart';

/// A client for running SSH based commands on a Fuchsia device.
@immutable
class SshClient {
  /// Creates a new SSH client.
  ///
  /// Relies on `ssh` being present in the $PATH.
  ///
  /// The `processManager` must not be null.
  const SshClient({
    this.processManager = const LocalProcessManager(),
  }) : assert(processManager != null);

  /// The [ProcessManager] to use for spawning `ssh`.
  final ProcessManager processManager;

  /// The default ssh timeout as [Duration] in milliseconds.
  static const Duration defaultSshTimeoutMs =
      Duration(milliseconds: 5 * 60 * 1000);

  /// Creates a list of arguments to pass to ssh.
  ///
  /// This method is not intended for use outside of this library, except for
  /// in unit tests.
  @visibleForTesting
  List<String> getSshArguments({
    String identityFilePath,
    String targetIp,
    List<String> command = const <String>[],
  }) {
    assert(command != null);
    return <String>[
      'ssh',
      '-o', 'CheckHostIP=no', //
      '-o', 'StrictHostKeyChecking=no',
      '-o', 'ForwardAgent=no',
      '-o', 'ForwardX11=no',
      '-o', 'GSSAPIDelegateCredentials=no',
      '-o', 'UserKnownHostsFile=/dev/null',
      '-o', 'User=fuchsia',
      '-o', 'IdentitiesOnly=yes',
      '-o', 'IdentityFile=$identityFilePath',
      '-o', 'ControlPersist=yes',
      '-o', 'ControlMaster=auto',
      '-o', 'ControlPath=/tmp/fuchsia--%r@%h:%p',
      '-o', 'ServerAliveInterval=1',
      '-o', 'ServerAliveCountMax=10',
      '-o', 'LogLevel=ERROR',
      targetIp,
      command.join(' '),
    ];
  }

  /// Creates an interactive SSH session.
  Future<OperationResult> interactive(
    String targetIp, {
    @required String identityFilePath,
  }) async {
    final Process ssh = await processManager.start(getSshArguments(
      targetIp: targetIp,
      identityFilePath: identityFilePath,
    ));
    ssh.stdout.transform(utf8.decoder).listen(stdout.writeln);
    ssh.stderr.transform(utf8.decoder).listen(stderr.writeln);
    stdin.pipe(ssh.stdin);

    final int exitCode = await ssh.exitCode;
    if (exitCode == 0) {
      return OperationResult.success();
    }
    return OperationResult.error('ssh exited with code $exitCode');
  }

  /// Runs an SSH command on the specified target IP.
  ///
  /// A target IP can be obtained from a device node name using the
  /// [FFX] class.
  ///
  /// All arguments must not be null.
  Future<OperationResult> runCommand(
    String targetIp, {
    @required String identityFilePath,
    @required List<String> command,
    Duration timeoutMs = defaultSshTimeoutMs,
    String logFilePath,
    FileSystem fs,
  }) async {
    assert(targetIp != null);
    assert(identityFilePath != null);
    assert(command != null);

    final bool logToFile = !(logFilePath == null || logFilePath.isEmpty);
    final FileSystem fileSystem = fs ?? const LocalFileSystem();
    PrintLogger logger;

    // If no file is passed to this method we create a memoryfile to keep to
    // return the stdout in OperationResult.
    if (logToFile) {
      fileSystem.file(logFilePath).existsSync() ??
          fileSystem.file(logFilePath).deleteSync();
      fileSystem.file(logFilePath).createSync();
      final IOSink data = fileSystem.file(logFilePath).openWrite();
      logger = PrintLogger(out: data);
    } else {
      logger = PrintLogger();
    }

    final Process process = await processManager.start(
      getSshArguments(
        identityFilePath: identityFilePath,
        targetIp: targetIp,
        command: command,
      ),
    );
    final StreamSubscription<String> stdoutSubscription = process.stdout
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .listen((String log) {
      logger.info(log);
    });
    final StreamSubscription<String> stderrSubscription = process.stderr
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .listen((String log) {
      logger.error(log);
    });

    // Wait for stdout and stderr to be fully processed because proc.exitCode
    // may complete first.
    await Future.wait<void>(<Future<void>>[
      stdoutSubscription.asFuture<void>(),
      stderrSubscription.asFuture<void>(),
    ]);

    await logger.flush();

    // The streams as futures have already completed, so waiting for the
    // potentially async stream cancellation to complete likely has no benefit.
    stdoutSubscription.cancel();
    stderrSubscription.cancel();

    final int exitCode = await process.exitCode.timeout(timeoutMs);

    return exitCode != 0
        ? OperationResult.error('Failed', info: logger.errorLog())
        : OperationResult.success(info: logger.outputLog());
  }
}
