// 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:path/path.dart' as p;
import 'package:stream_channel/stream_channel.dart';

import '../../test.dart';
import '../backend/invoker.dart';
import '../util/remote_exception.dart';
import '../utils.dart';

/// 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()`.
final _transformer = new StreamChannelTransformer<Object, Map>(
    new StreamTransformer.fromHandlers(handleData: (message, sink) {
  switch (message["type"]) {
    case "data":
      sink.add(message["data"]);
      break;

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

    case "error":
      var error = RemoteException.deserialize(message["error"]);
      sink.addError(error.error, error.stackTrace);
      break;
  }
}), new 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 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(uri, {Object message, bool stayAlive: false}) {
  Uri parsedUrl;
  if (uri is Uri) {
    parsedUrl = uri;
  } else if (uri is String) {
    parsedUrl = Uri.parse(uri);
  } else {
    throw new ArgumentError.value(uri, "uri", "must be a Uri or a String.");
  }

  String absoluteUri;
  if (parsedUrl.scheme.isEmpty) {
    var suitePath = Invoker.current.liveTest.suite.path;
    absoluteUri = p.url.join(
        p.url.dirname(p.toUri(p.absolute(suitePath)).toString()),
        parsedUrl.toString());
  } else {
    absoluteUri = uri.toString();
  }

  return _spawn(absoluteUri, 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 = new Uri.dataFromString(dartCode,
      encoding: UTF8, mimeType: 'application/dart');
  return _spawn(uri.toString(), message, stayAlive: stayAlive);
}

/// Like [spawnHybridUri], but doesn't take [Uri] objects and doesn't handle
/// relative URLs.
StreamChannel _spawn(String uri, Object message, {bool stayAlive: false}) {
  var channel = Zone.current[#test.runner.test_channel] as MultiChannel;
  if (channel == null) {
    // TODO(nweiz): Link to an issue tracking support when running the test file
    // directly.
    throw new UnsupportedError("Can't connect to the test runner.\n"
        'spawnHybridUri() is currently only supported within "pub run test".');
  }

  ensureJsonEncodable(message);

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

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

  return isolateChannel.transform(_transformer);
}
