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

// @dart = 2.8

/// Convenience methods for Flutter application driving on Fuchsia. Can
/// be run on either a host machine (making a remote connection to a Fuchsia
/// device), or on the target Fuchsia machine.
import 'dart:io';

import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart';

import 'error.dart';

class _DummyPortForwarder implements PortForwarder {
  _DummyPortForwarder(this._port, this._remotePort);

  final int _port;
  final int _remotePort;

  @override
  int get port => _port;

  @override
  int get remotePort => _remotePort;

  @override
  String get openPortAddress => InternetAddress.loopbackIPv4.address;

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

class _DummySshCommandRunner implements SshCommandRunner {
  _DummySshCommandRunner();

  void _log(String message) {
    driverLog('_DummySshCommandRunner', message);
  }

  @override
  String get sshConfigPath => null;

  @override
  String get address => InternetAddress.loopbackIPv4.address;

  @override
  String get interface => null;

  @override
  Future<List<String>> run(String command) async {
    try {
      final List<String> splitCommand = command.split(' ');
      final String exe = splitCommand[0];
      final List<String> args = splitCommand.skip(1).toList();
      // This needs to remain async in the event that this command attempts to
      // access something (like the hub) that requires interaction with this
      // process's event loop. A specific example is attempting to run `find`, a
      // synchronous command, on this own process's `out` directory. As `find`
      // will wait indefinitely for the `out` directory to be serviced, causing
      // a deadlock.
      final ProcessResult r = await Process.run(exe, args);
      return (r.stdout as String).split('\n');
    } on ProcessException catch (e) {
      _log("Error running '$command': $e");
    }
    return <String>[];
  }
}

Future<PortForwarder> _dummyPortForwardingFunction(
  String address,
  int remotePort, [
  String interface = '',
  String configFile,
]) async {
  return _DummyPortForwarder(remotePort, remotePort);
}

/// Utility class for creating connections to the Fuchsia Device.
///
/// If executed on a host (non-Fuchsia device), behaves the same as running
/// [FuchsiaRemoteConnection.connect] whereby the `FUCHSIA_REMOTE_URL` and
/// `FUCHSIA_SSH_CONFIG` variables must be set. If run on a Fuchsia device, will
/// connect locally without need for environment variables.
class FuchsiaCompat {
  static void _init() {
    fuchsiaPortForwardingFunction = _dummyPortForwardingFunction;
  }

  /// Restores state to normal if running on a Fuchsia device.
  ///
  /// Noop if running on the host machine.
  static void cleanup() {
    restoreFuchsiaPortForwardingFunction();
  }

  /// Creates a connection to the Fuchsia device's Dart VM's.
  ///
  /// See [FuchsiaRemoteConnection.connect] for more details.
  /// [FuchsiaCompat.cleanup] must be called when the connection is no longer in
  /// use. It is the caller's responsibility to call
  /// [FuchsiaRemoteConnection.stop].
  static Future<FuchsiaRemoteConnection> connect() async {
    FuchsiaCompat._init();
    return FuchsiaRemoteConnection.connectWithSshCommandRunner(
        _DummySshCommandRunner());
  }
}
