// 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:developer';
import 'dart:io';
import 'dart:isolate';

import 'package:coverage/coverage.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:vm_service/vm_service.dart' hide Isolate;
import 'package:vm_service/vm_service_io.dart';

import '../../runner/configuration.dart';
import '../../runner/environment.dart';
import '../../runner/load_exception.dart';
import '../../runner/platform.dart';
import '../../runner/plugin/platform_helpers.dart';
import '../../runner/runner_suite.dart';
import '../../runner/suite.dart';
import '../../util/dart.dart' as dart;
import 'environment.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();

  @override
  StreamChannel loadChannel(String path, SuitePlatform platform) =>
      throw UnimplementedError();

  @override
  Future<RunnerSuite> load(String path, SuitePlatform platform,
      SuiteConfiguration suiteConfig, Object message) async {
    assert(platform.runtime == Runtime.vm);

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

    VmService client;
    StreamSubscription<Event> eventSub;
    var channel = IsolateChannel.connectReceive(receivePort)
        .transformStream(StreamTransformer.fromHandlers(handleDone: (sink) {
      isolate.kill();
      eventSub?.cancel();
      client?.dispose();
      sink.close();
    }));

    Environment environment;
    IsolateRef isolateRef;
    if (_config.debug) {
      // Print an empty line because the VM prints an "Observatory listening on"
      // line and we don't want that to end up on the same line as the reporter
      // info.
      if (_config.reporter == 'compact') stdout.writeln();

      var info = await Service.controlWebServer(enable: true);
      var isolateID = Service.getIsolateID(isolate);

      var libraryPath = p.toUri(p.absolute(path)).toString();
      client = await vmServiceConnectUri(_wsUriFor(info.serverUri.toString()));
      var isolateNumber = int.parse(isolateID.split('/').last);
      isolateRef = (await client.getVM())
          .isolates
          .firstWhere((isolate) => isolate.number == isolateNumber.toString());
      await client.setName(isolateRef.id, path);
      var libraryRef = (await client.getIsolate(isolateRef.id))
          .libraries
          .firstWhere((library) => library.uri == libraryPath) as LibraryRef;
      var url = _observatoryUrlFor(
          info.serverUri.toString(), isolateRef.id, libraryRef.id);
      environment = VMEnvironment(url, isolateRef, client);
    }

    environment ??= PluginEnvironment();

    var controller = deserializeSuite(
        path, platform, suiteConfig, environment, channel, message,
        gatherCoverage: () => _gatherCoverage(environment));

    if (isolateRef != null) {
      await client.streamListen('Debug');
      eventSub = client.onDebugEvent.listen((event) {
        if (event.kind == EventKind.kResume) {
          controller.setDebugging(false);
        } else if (event.kind == EventKind.kPauseInterrupted ||
            event.kind == EventKind.kPauseBreakpoint ||
            event.kind == EventKind.kPauseException) {
          controller.setDebugging(true);
        }
      });
    }

    return await controller.suite;
  }

  /// 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.suiteDefaults.precompiledPath != null) {
      return _spawnPrecompiledIsolate(
          path, message, _config.suiteDefaults.precompiledPath);
    } else if (_config.pubServeUrl != null) {
      return _spawnPubServeIsolate(path, message, _config.pubServeUrl);
    } else {
      return _spawnDataIsolate(path, message);
    }
  }
}

Future<Isolate> _spawnDataIsolate(String path, SendPort message) async {
  return await dart.runInIsolate('''
    import "dart:isolate";

    import "package:stream_channel/isolate_channel.dart";

    import "package:test_core/src/runner/plugin/remote_platform_helpers.dart";

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

    void main(_, SendPort message) {
      var channel = serializeSuite(() => test.main);
      IsolateChannel.connectSend(message).pipe(channel);
    }
  ''', message);
}

Future<Isolate> _spawnPrecompiledIsolate(
    String testPath, SendPort message, String precompiledPath) async {
  testPath = p.absolute(p.join(precompiledPath, testPath) + '.vm_test.dart');
  var dillTestpath =
      testPath.substring(0, testPath.length - '.dart'.length) + '.vm.app.dill';
  if (await File(dillTestpath).exists()) {
    testPath = dillTestpath;
  }
  return await Isolate.spawnUri(p.toUri(testPath), [], message,
      packageConfig: p.toUri(p.join(precompiledPath, '.packages')),
      checked: true);
}

Future<Map<String, dynamic>> _gatherCoverage(Environment environment) async {
  final isolateId = Uri.parse(environment.observatoryUrl.fragment)
      .queryParameters['isolateId'];
  return await collect(environment.observatoryUrl, false, false, false, {},
      isolateIds: {isolateId});
}

Future<Isolate> _spawnPubServeIsolate(
    String testPath, SendPort message, Uri pubServeUrl) async {
  var url = pubServeUrl.resolveUri(
      p.toUri(p.relative(testPath, 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 LoadException(
          testPath,
          'Error getting $url: Connection refused\n'
          'Make sure "pub serve" is running.');
    } else if (error.message.contains('404 Not Found')) {
      throw LoadException(
          testPath,
          'Error getting $url: 404 Not Found\n'
          'Make sure "pub serve" is serving the test/ directory.');
    }

    throw LoadException(testPath, error);
  }
}

String _wsUriFor(String observatoryUrl) =>
    "ws:${observatoryUrl.split(':').sublist(1).join(':')}ws";

Uri _observatoryUrlFor(String base, String isolateId, String id) =>
    Uri.parse('$base#/inspect?isolateId=${Uri.encodeQueryComponent(isolateId)}&'
        'objectId=${Uri.encodeQueryComponent(id)}');
