// 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:isolate';

import 'package:path/path.dart' as p;
import 'package:stream_channel/stream_channel.dart';

import '../../backend/test_platform.dart';
import '../../util/dart.dart' as dart;
import '../configuration.dart';
import '../load_exception.dart';
import '../plugin/platform.dart';

/// A platform that loads tests in isolates spawned within this Dart process.
class VMPlatform extends PlatformPlugin {
  /// The test runner configuration.
  final _config = Configuration.current;

  VMPlatform();

  StreamChannel loadChannel(String path, TestPlatform platform) {
    assert(platform == TestPlatform.vm);

    var isolate;
    var channel = StreamChannelCompleter.fromFuture(() async {
      var receivePort = new ReceivePort();

      try {
        isolate = await _spawnIsolate(path, receivePort.sendPort);
      } catch (error) {
        receivePort.close();
        rethrow;
      }

      return new IsolateChannel.connectReceive(receivePort);
    }());

    // Once the connection is closed by either end, kill the isolate.
    return channel
        .transformStream(new StreamTransformer.fromHandlers(handleDone: (sink) {
      if (isolate != null) isolate.kill();
      sink.close();
    }));
  }

  /// Spawns an isolate and passes it [message].
  ///
  /// This isolate connects an [IsolateChannel] to [message] and sends the
  /// serialized tests over that channel.
  Future<Isolate> _spawnIsolate(String path, SendPort message) async {
    if (_config.pubServeUrl == null) {
      return await dart.runInIsolate(
          '''
        import "dart:isolate";

        import "package:stream_channel/stream_channel.dart";

        import "package:test/src/runner/plugin/remote_platform_helpers.dart";
        import "package:test/src/runner/vm/catch_isolate_errors.dart";

        import "${p.toUri(p.absolute(path))}" as test;

        void main(_, SendPort message) {
          var channel = serializeSuite(() {
            catchIsolateErrors();
            return test.main;
          });
          new IsolateChannel.connectSend(message).pipe(channel);
        }
      ''',
          message,
          checked: true);
    }

    var url = _config.pubServeUrl
        .resolveUri(p.toUri(p.relative(path, from: 'test') + '.vm_test.dart'));

    try {
      return await Isolate.spawnUri(url, [], message, checked: true);
    } on IsolateSpawnException catch (error) {
      if (error.message.contains("OS Error: Connection refused") ||
          error.message.contains("The remote computer refused")) {
        throw new LoadException(
            path,
            "Error getting $url: Connection refused\n"
            'Make sure "pub serve" is running.');
      } else if (error.message.contains("404 Not Found")) {
        throw new LoadException(
            path,
            "Error getting $url: 404 Not Found\n"
            'Make sure "pub serve" is serving the test/ directory.');
      }

      throw new LoadException(path, error);
    }
  }
}
