// 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.
//
// @dart=2.9

import 'dart:io';
import 'dart:isolate';

import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:async/async.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';

import '../util/dart.dart' as dart;
import '../util/package_config.dart';

import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports

/// Spawns a hybrid isolate from [url] with the given [message], and returns a
/// [StreamChannel] that communicates with it.
///
/// This connects the main isolate to the hybrid isolate, whereas
/// `lib/src/frontend/spawn_hybrid.dart` connects the test isolate to the main
/// isolate.
///
/// If [uri] is relative, it will be interpreted relative to the `file:` URL
/// for [suite]. 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.
StreamChannel /*!*/ spawnHybridUri(
    String url, Object /*?*/ message, Suite suite) {
  url = _normalizeUrl(url, suite);
  return StreamChannelCompleter.fromFuture(() async {
    var port = ReceivePort();
    var onExitPort = ReceivePort();
    try {
      var code = '''
        ${await _languageVersionCommentFor(url)}

        import "package:test_core/src/runner/hybrid_listener.dart";

        import "${url.replaceAll(r'$', '%24')}" as lib;

        void main(_, List data) => listen(() => lib.hybridMain, data);
      ''';

      var isolate = await dart.runInIsolate(code, [port.sendPort, message],
          onExit: onExitPort.sendPort);

      // Ensure that we close [port] and [channel] when the isolate exits.
      var disconnector = Disconnector();
      onExitPort.listen((_) {
        disconnector.disconnect();
        onExitPort.close();
      });

      return IsolateChannel.connectReceive(port)
          .transform(disconnector)
          .transformSink(StreamSinkTransformer.fromHandlers(handleDone: (sink) {
        // If the user closes the stream channel, kill the isolate.
        isolate.kill();
        onExitPort.close();
        sink.close();
      }));
    } catch (error, stackTrace) {
      port.close();
      onExitPort.close();

      // Make sure any errors in spawning the isolate are forwarded to the test.
      return StreamChannel(
          Stream.fromFuture(Future.value({
            'type': 'error',
            'error': RemoteException.serialize(error, stackTrace)
          })),
          NullStreamSink());
    }
  }());
}

/// Normalizes [url] to an absolute url, or returns it as is if it has a
/// scheme.
///
/// Follows the rules for relative/absolute paths outlined in [spawnHybridUri].
String _normalizeUrl(String url, Suite suite) {
  final parsedUri = Uri.parse(url);

  if (parsedUri.scheme.isEmpty) {
    var isRootRelative = parsedUri.path.startsWith('/');

    if (isRootRelative) {
      // We assume that the current path is the package root. `pub run`
      // enforces this currently, but at some point it would probably be good
      // to pass in an explicit root.
      return p.url
          .join(p.toUri(p.current).toString(), parsedUri.path.substring(1));
    } else {
      var suitePath = suite.path;
      return p.url.join(
          p.url.dirname(p.toUri(p.absolute(suitePath)).toString()),
          parsedUri.toString());
    }
  } else {
    return url;
  }
}

/// Computes the a language version comment for the library at [uri].
///
/// If there is a language version comment in the file, that is returned.
///
/// Otherwise a comment representing the default version from the
/// [currentPackageConfig] is returned.
///
/// If no default language version is known (data: uri for instance), then
/// an empty string is returned.
Future<String> _languageVersionCommentFor(String url) async {
  var parsedUri = Uri.parse(url);

  // Returns the explicit language version comment if one exists.
  var result = parseString(
      content: await _readUri(parsedUri),
      path: parsedUri.scheme == 'data' ? null : p.fromUri(parsedUri),
      throwIfDiagnostics: false);
  var languageVersionComment = result.unit.languageVersionToken?.value();
  if (languageVersionComment != null) return languageVersionComment.toString();

  // Returns the default language version for the package if one exists.
  if (parsedUri.scheme.isEmpty || parsedUri.scheme == 'file') {
    var packageConfig = await currentPackageConfig;
    var package = packageConfig.packageOf(parsedUri);
    var version = package?.languageVersion;
    if (version != null) return '// @dart=${version}';
  }

  // Fall back on no language comment.
  return '';
}

Future<String> _readUri(Uri uri) async {
  switch (uri.scheme) {
    case '':
    case 'file':
      return File.fromUri(uri).readAsString();
    case 'data':
      return uri.data.contentAsString();
    default:
      throw ArgumentError.value(uri, 'uri',
          'Only data and file uris (as well as relative paths) are supported');
  }
}
