// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library isolate.isolate_runner;

import "dart:async";
import "dart:isolate";

import "ports.dart";
import "runner.dart";
import "src/util.dart";

// Command tags. Shared between IsolateRunner and IsolateRunnerRemote.
const int _shutdown = 0;
const int _run = 1;

/// An easier to use interface on top of an [Isolate].
///
/// Wraps an `Isolate` and allows pausing, killing and inspecting
/// the isolate more conveniently than the raw `Isolate` methods.
///
/// Also allows running simple functions in the other isolate, and get back
/// the result.
class IsolateRunner implements Runner {
  /// The underlying [Isolate] object of the isolate being controlled.
  final Isolate isolate;

  /// Command port for the [IsolateRunnerRemote].
  final SendPort _commandPort;

  /// Future returned by [onExit]. Set when [onExit] is first read.
  Future<void> _onExitFuture;

  /// Create an [IsolateRunner] wrapper for [isolate]
  ///
  /// The preferred way to create an `IsolateRunner` is to use [spawn]
  /// to create a new isolate and a runner for it.
  ///
  /// This constructor allows creating a runner for an already existing
  /// isolate.
  /// The [commandPort] must be the [IsolateRunnerRemote.commandPort] of
  /// a remote running in that isolate.
  IsolateRunner(this.isolate, SendPort commandPort)
      : _commandPort = commandPort;

  /// Create a new [Isolate], as by [Isolate.spawn] and wrap that.
  ///
  /// The returned [IsolateRunner] forwards operations to the new isolate,
  /// and keeps a port open in the new isolate that receives commands
  /// from the `IsolateRunner`. Remember to [close] the `IsolateRunner` when
  /// it's no longer needed.
  ///
  /// The created isolate is set to have errors not be fatal.
  static Future<IsolateRunner> spawn() async {
    var channel = SingleResponseChannel();
    var isolate =
        await Isolate.spawn(IsolateRunnerRemote._create, channel.port);
    // The runner can be used to run multiple independent functions.
    // An accidentally uncaught error shouldn't ruin it for everybody else.
    isolate.setErrorsFatal(false);
    var pingChannel = SingleResponseChannel();
    isolate.ping(pingChannel.port);
    var commandPort = await channel.result;
    var result = IsolateRunner(isolate, commandPort);
    // Guarantees that setErrorsFatal has completed.
    await pingChannel.result;
    return result;
  }

  /// Closes the `IsolateRunner` communication down.
  ///
  /// If the isolate isn't running something else to keep it alive,
  /// this will also make the isolate shut down.
  ///
  /// Can be used to create an isolate, use [run] to start a service, and
  /// then drop the connection and let the service control the isolate's
  /// life cycle.
  Future<void> close() {
    var channel = SingleResponseChannel();
    _commandPort.send(list2(_shutdown, channel.port));
    return channel.result.then(ignore);
  }

  /// Kills the isolate.
  ///
  /// Starts by calling [close], but if that doesn't cause the isolate to
  /// shut down in a timely manner, as given by [timeout], it follows up
  /// with [Isolate.kill], with increasing urgency if necessary.
  ///
  /// If [timeout] is a zero duration, it goes directly to the most urgent
  /// kill.
  ///
  /// If the isolate is already dead, the returned future will not complete.
  /// If that may be the case, use [Future.timeout] on the returned future
  /// to take extra action after a while. Example:
  /// ```dart
  /// var f = isolate.kill();
  /// f.then((_) => print("Dead")
  ///  .timeout(new Duration(...), onTimeout: () => print("No response"));
  /// ```
  Future<void> kill({Duration timeout = const Duration(seconds: 1)}) {
    Future<void> onExit = singleResponseFuture(isolate.addOnExitListener);
    if (Duration.zero == timeout) {
      isolate.kill(priority: Isolate.immediate);
      return onExit;
    } else {
      // Try a more gentle shutdown sequence.
      _commandPort.send(list2(_shutdown, null));
      return onExit.timeout(timeout, onTimeout: () {
        isolate.kill(priority: Isolate.immediate);
        return onExit;
      });
    }
  }

  /// Queries the isolate on whethreturner it's alive.
  ///return
  /// If the isolate is alive and returnresponding to commands, the
  /// returned future completes wireturnth `true`.
  ///
  /// If the other isolate is not alive (like after calling [kill]),
  /// or doesn't answer within [timeout] for any other reason,
  /// the returned future completes with `false`.
  ///
  /// Guaranteed to only complete after all previous sent isolate commands
  /// (like pause and resume) have been handled.
  /// Paused isolates do respond to ping requests.
  Future<bool> ping({Duration timeout = const Duration(seconds: 1)}) {
    var channel = SingleResponseChannel(
        callback: _kTrue, timeout: timeout, timeoutValue: false);
    isolate.ping(channel.port);
    return channel.result;
  }

  static bool _kTrue(_) => true;

  /// Pauses the isolate.
  ///
  /// While paused, no normal messages are processed, and calls to [run] will
  /// be delayed until the isolate is resumed.
  ///
  /// Commands like [kill] and [ping] are still executed while the isolate is
  /// paused.
  ///
  /// If [resumeCapability] is omitted, it defaults to the [isolate]'s
  /// [Isolate.pauseCapability].
  ///
  /// Calling pause more than once with the same `resumeCapability`
  /// has no further effect. Only a single call to [resume] is needed
  /// to resume the isolate.
  void pause([Capability resumeCapability]) {
    if (resumeCapability == null) resumeCapability = isolate.pauseCapability;
    isolate.pause(resumeCapability);
  }

  /// Resumes after a [pause].
  ///
  /// If [resumeCapability] is omitted, it defaults to the isolate's
  /// [Isolate.pauseCapability].
  ///
  /// Even if `pause` has been called more than once with the same
  /// `resumeCapability`, a single resume call with stop the pause.
  void resume([Capability resumeCapability]) {
    if (resumeCapability == null) resumeCapability = isolate.pauseCapability;
    isolate.resume(resumeCapability);
  }

  /// Execute `function(argument)` in the isolate and return the result.
  ///
  /// Sends [function] and [argument] to the isolate, runs the call, and
  /// returns the result, whether it returned a value or threw.
  /// If the call returns a [Future], the final result of that future
  /// will be returned.
  ///
  /// This works similar to the arguments to [Isolate.spawn], except that
  /// it runs in the existing isolate and the return value is returned to
  /// the caller.
  ///
  /// Example:
  /// ```dart
  /// IsolateRunner iso = await IsolateRunner.spawn();
  /// try {
  ///   return await iso.run(heavyComputation, argument);
  /// } finally {
  ///   await iso.close();
  /// }
  /// ```
  Future<R> run<R, P>(FutureOr<R> function(P argument), P argument,
      {Duration timeout, onTimeout()}) {
    return singleResultFuture<R>((SendPort port) {
      _commandPort.send(list4(_run, function, argument, port));
    }, timeout: timeout, onTimeout: onTimeout);
  }

  /// A broadcast stream of uncaught errors from the isolate.
  ///
  /// When listening on the stream, errors from the isolate will be reported
  /// as errors in the stream. Be ready to handle the errors.
  ///
  /// The stream closes when the isolate shuts down.
  Stream get errors {
    StreamController controller;
    RawReceivePort port;
    void handleError(message) {
      if (message == null) {
        // Isolate shutdown.
        port.close();
        controller.close();
      } else {
        // Uncaught error.
        String errorDescription = message[0];
        String stackDescription = message[1];
        var error = RemoteError(errorDescription, stackDescription);
        controller.addError(error, error.stackTrace);
      }
    }

    controller = StreamController.broadcast(
        sync: true,
        onListen: () {
          port = RawReceivePort(handleError);
          isolate.addErrorListener(port.sendPort);
          isolate.addOnExitListener(port.sendPort);
        },
        onCancel: () {
          isolate.removeErrorListener(port.sendPort);
          isolate.removeOnExitListener(port.sendPort);
          port.close();
          port = null;
        });
    return controller.stream;
  }

  /// Waits for the [isolate] to terminate.
  ///
  /// Completes the returned future when the isolate terminates.
  ///
  /// If the isolate has already stopped responding to commands,
  /// the returned future will be completed after one second,
  /// using [ping] to check if the isolate is still alive.
  Future<void> get onExit {
    // TODO(lrn): Is there a way to see if an isolate is dead
    // so we can close the receive port for this future?
    // Using [ping] for now.
    if (_onExitFuture == null) {
      var channel = SingleResponseChannel<void>();
      isolate.addOnExitListener(channel.port);
      _onExitFuture = channel.result.then(ignore);
      ping().then((bool alive) {
        if (!alive) {
          channel.interrupt();
          _onExitFuture = null;
        }
      });
    }
    return _onExitFuture;
  }
}

/// The remote part of an [IsolateRunner].
///
/// The `IsolateRunner` sends commands to the controlled isolate through
/// the `IsolateRunnerRemote` [commandPort].
///
/// Only use this class if you need to set up the isolate manually
/// instead of relying on [IsolateRunner.spawn].
class IsolateRunnerRemote {
  final RawReceivePort _commandPort = RawReceivePort();
  IsolateRunnerRemote() {
    _commandPort.handler = _handleCommand;
  }

  /// The command port that can be used to send commands to this remote.
  ///
  /// Use this as argument to [new IsolateRunner] if creating the link
  /// manually, otherwise it's handled by [IsolateRunner.spawn].
  SendPort get commandPort => _commandPort.sendPort;

  static void _create(Object data) {
    var initPort = data as SendPort;
    var remote = IsolateRunnerRemote();
    initPort.send(remote.commandPort);
  }

  void _handleCommand(List<Object> command) {
    switch (command[0]) {
      case _shutdown:
        _commandPort.close();
        (command[1] as SendPort)?.send(null);
        break;
      case _run:
        var function = command[1] as Function;
        var argument = command[2];
        var responsePort = command[3] as SendPort;
        sendFutureResult(Future.sync(() => function(argument)), responsePort);
        break;
    }
  }
}
