// Copyright (c) 2016, 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.

import 'dart:async';
import 'dart:convert';

import 'package:async/async.dart';
import 'package:stream_channel/stream_channel.dart';

import '../backend/remote_exception.dart';
import '../utils.dart';
import 'test_structure.dart' show addTearDown;

/// A transformer that handles messages from the spawned isolate and ensures
/// that messages sent to it are JSON-encodable.
///
/// The spawned isolate sends three kinds of messages. Data messages are emitted
/// as data events, error messages are emitted as error events, and print
/// messages are printed using `print()`.
// package:test will only send a `Map` across this channel, but users of
// `hybridMain` can send any json encodeable type.
final _transformer = StreamChannelTransformer<dynamic, dynamic>(
    StreamTransformer.fromHandlers(handleData: (message, sink) {
  switch (message['type'] as String) {
    case 'data':
      sink.add(message['data']);
      break;

    case 'print':
      print(message['line']);
      break;

    case 'error':
      var error = RemoteException.deserialize(message['error'] as Map);
      sink.addError(error.error, error.stackTrace);
      break;
  }
}), StreamSinkTransformer.fromHandlers(handleData: (message, sink) {
  // This is called synchronously from the user's `Sink.add()` call, so if
  // [ensureJsonEncodable] throws here they'll get a helpful stack trace.
  ensureJsonEncodable(message);
  sink.add(message);
}));

/// Spawns a VM isolate for the given [uri], which may be a [Uri] or a [String].
///
/// This allows browser tests to spawn servers with which they can communicate
/// to test client/server interactions. It can also be used by VM tests to
/// easily spawn an isolate.
///
/// The Dart file at [uri] must define a top-level `hybridMain()` function that
/// takes a `StreamChannel` argument and, optionally, an `Object` argument to
/// which [message] will be passed. Note that [message] must be JSON-encodable.
/// For example:
///
/// ```dart
/// import "package:stream_channel/stream_channel.dart";
///
/// hybridMain(StreamChannel channel, Object message) {
///   // ...
/// }
/// ```
///
/// If [uri] is relative, it will be interpreted relative to the `file:` URL for
/// the test suite being executed. If it's root-relative (that is, if it begins
/// with `/`) it will be interpreted relative to the root of the package (the
/// directory that contains `pubspec.yaml`, *not* the `test/` directory). If
/// it's a `package:` URL, it will be resolved using the current package's
/// dependency constellation.
///
/// Returns a [StreamChannel] that's connected to the channel passed to
/// `hybridMain()`. Only JSON-encodable objects may be sent through this
/// channel. If the channel is closed, the hybrid isolate is killed. If the
/// isolate is killed, the channel's stream will emit a "done" event.
///
/// Any unhandled errors loading or running the hybrid isolate will be emitted
/// as errors over the channel's stream. Any calls to `print()` in the hybrid
/// isolate will be printed as though they came from the test that created the
/// isolate.
///
/// Code in the hybrid isolate is not considered to be running in a test
/// context, so it can't access test functions like `expect()` and
/// `expectAsync()`.
///
/// By default, the hybrid isolate is automatically killed when the test
/// finishes running. If [stayAlive] is `true`, it won't be killed until the
/// entire test suite finishes running.
///
/// **Note**: If you use this API, be sure to add a dependency on the
/// **`stream_channel` package, since you're using its API as well!
StreamChannel spawnHybridUri(
  Object uri, {
  Object? message,
  bool stayAlive = false,
}) {
  if (uri is String) {
    // Ensure that it can be parsed as a uri.
    Uri.parse(uri);
  } else if (uri is! Uri) {
    throw ArgumentError.value(uri, 'uri', 'must be a Uri or a String.');
  }
  return _spawn(uri.toString(), message, stayAlive: stayAlive);
}

/// Spawns a VM isolate that runs the given [dartCode], which is loaded as the
/// contents of a Dart library.
///
/// This allows browser tests to spawn servers with which they can communicate
/// to test client/server interactions. It can also be used by VM tests to
/// easily spawn an isolate.
///
/// The [dartCode] must define a top-level `hybridMain()` function that takes a
/// `StreamChannel` argument and, optionally, an `Object` argument to which
/// [message] will be passed. Note that [message] must be JSON-encodable. For
/// example:
///
/// ```dart
/// import "package:stream_channel/stream_channel.dart";
///
/// hybridMain(StreamChannel channel, Object message) {
///   // ...
/// }
/// ```
///
/// Returns a [StreamChannel] that's connected to the channel passed to
/// `hybridMain()`. Only JSON-encodable objects may be sent through this
/// channel. If the channel is closed, the hybrid isolate is killed. If the
/// isolate is killed, the channel's stream will emit a "done" event.
///
/// Any unhandled errors loading or running the hybrid isolate will be emitted
/// as errors over the channel's stream. Any calls to `print()` in the hybrid
/// isolate will be printed as though they came from the test that created the
/// isolate.
///
/// Code in the hybrid isolate is not considered to be running in a test
/// context, so it can't access test functions like `expect()` and
/// `expectAsync()`.
///
/// By default, the hybrid isolate is automatically killed when the test
/// finishes running. If [stayAlive] is `true`, it won't be killed until the
/// entire test suite finishes running.
///
/// **Note**: If you use this API, be sure to add a dependency on the
/// **`stream_channel` package, since you're using its API as well!
StreamChannel spawnHybridCode(String dartCode,
    {Object? message, bool stayAlive = false}) {
  var uri = Uri.dataFromString(dartCode,
      encoding: utf8, mimeType: 'application/dart');
  return _spawn(uri.toString(), message, stayAlive: stayAlive);
}

/// Like [spawnHybridUri], but doesn't take [Uri] objects.
StreamChannel _spawn(String uri, Object? message, {bool stayAlive = false}) {
  var channel = Zone.current[#test.runner.test_channel] as MultiChannel?;
  if (channel == null) {
    throw UnsupportedError("Can't connect to the test runner.\n"
        'spawnHybridUri() is currently only supported within "dart test".');
  }

  ensureJsonEncodable(message);

  var virtualChannel = channel.virtualChannel();
  StreamChannel isolateChannel = virtualChannel;
  channel.sink.add({
    'type': 'spawn-hybrid-uri',
    'url': uri,
    'message': message,
    'channel': virtualChannel.id
  });

  if (!stayAlive) {
    var disconnector = Disconnector<void>();
    addTearDown(() => disconnector.disconnect());
    isolateChannel = isolateChannel.transform(disconnector);
  }

  return isolateChannel.transform(_transformer);
}
