// 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: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_version.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.
///
/// If the URI has a `data` scheme, a comment representing the language version of
/// the current package is returned.
///
/// Otherwise a comment representing the default version from the
/// [currentPackageConfig] is returned.
///
/// If no default language version is known (the URI scheme is not recognized
/// 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';
  }

  // Returns the root package language version for `data` URIs. These are
  // assumed to be from `spawnHybridCode` calls.
  if (parsedUri.scheme == 'data') {
    return await rootPackageLanguageVersionComment;
  }

  // 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');
  }
}
