// Copyright (c) 2017, 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 'dart:io';

import 'package:async/async.dart';
import 'package:node_preamble/preamble.dart' as preamble;
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/backend.dart'
    show Compiler, Runtime, StackTraceMapper, SuitePlatform;
import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/dart2js_compiler_pool.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/package_version.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/platform.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/plugin/customizable_platform.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/plugin/environment.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/wasm_compiler_pool.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/errors.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/package_config.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
import 'package:yaml/yaml.dart';

import '../../util/package_map.dart';
import '../executable_settings.dart';

/// A platform that loads tests in Node.js processes.
class NodePlatform extends PlatformPlugin
    implements CustomizablePlatform<ExecutableSettings> {
  /// The test runner configuration.
  final Configuration _config;

  /// The [Dart2JsCompilerPool] managing active instances of `dart2js`.
  final _jsCompilers = Dart2JsCompilerPool(['-Dnode=true', '--server-mode']);
  final _wasmCompilers = WasmCompilerPool(['-Dnode=true']);

  /// The temporary directory in which compiled JS is emitted.
  final _compiledDir = createTempDir();

  /// Executable settings for [Runtime.nodeJS] and runtimes that extend
  /// it.
  final _settings = {
    Runtime.nodeJS: ExecutableSettings(
      linuxExecutable: 'node',
      macOSExecutable: 'node',
      windowsExecutable: 'node.exe',
    ),
  };

  NodePlatform() : _config = Configuration.current;

  @override
  ExecutableSettings parsePlatformSettings(YamlMap settings) =>
      ExecutableSettings.parse(settings);

  @override
  ExecutableSettings mergePlatformSettings(
    ExecutableSettings settings1,
    ExecutableSettings settings2,
  ) => settings1.merge(settings2);

  @override
  void customizePlatform(Runtime runtime, ExecutableSettings settings) {
    var oldSettings = _settings[runtime] ?? _settings[runtime.root];
    if (oldSettings != null) settings = oldSettings.merge(settings);
    _settings[runtime] = settings;
  }

  @override
  Future<RunnerSuite> load(
    String path,
    SuitePlatform platform,
    SuiteConfiguration suiteConfig,
    Map<String, Object?> message,
  ) async {
    if (platform.compiler != Compiler.dart2js &&
        platform.compiler != Compiler.dart2wasm) {
      throw StateError(
        'Unsupported compiler for the Node platform ${platform.compiler}.',
      );
    }
    var (channel, stackMapper) = await _loadChannel(
      path,
      platform,
      suiteConfig,
    );
    var controller = deserializeSuite(
      path,
      platform,
      suiteConfig,
      const PluginEnvironment(),
      channel,
      message,
    );

    controller.channel('test.node.mapper').sink.add(stackMapper?.serialize());

    return await controller.suite;
  }

  /// Loads a [StreamChannel] communicating with the test suite at [path].
  ///
  /// Returns that channel along with a [StackTraceMapper] representing the
  /// source map for the compiled suite.
  Future<(StreamChannel<Object?>, StackTraceMapper?)> _loadChannel(
    String path,
    SuitePlatform platform,
    SuiteConfiguration suiteConfig,
  ) async {
    final servers = await _loopback();

    try {
      var (process, stackMapper) = await _spawnProcess(
        path,
        platform,
        suiteConfig,
        servers.first.port,
      );

      // Forward Node's standard IO to the print handler so it's associated with
      // the load test.
      //
      // TODO(nweiz): Associate this with the current test being run, if any.
      process.stdout.transform(lineSplitter).listen(print);
      process.stderr.transform(lineSplitter).listen(print);

      // Wait for the first connection (either over ipv4 or v6). If the proccess
      // exits before it connects, throw instead of waiting for a connection
      // indefinitely.
      var socket = await Future.any([
        StreamGroup.merge(servers).first,
        process.exitCode.then((_) => null),
      ]);

      if (socket == null) {
        throw LoadException(
          path,
          'Node exited before connecting to the test channel.',
        );
      }

      var channel = StreamChannel(socket.cast<List<int>>(), socket)
          .transform(StreamChannelTransformer.fromCodec(utf8))
          .transform(_chunksToLines)
          .transform(jsonDocument)
          .transformStream(
            StreamTransformer.fromHandlers(
              handleDone: (sink) {
                process.kill();
                sink.close();
              },
            ),
          );

      return (channel, stackMapper);
    } finally {
      unawaited(
        Future.wait<void>(
          servers.map(
            (s) =>
                s.close().then<ServerSocket?>((v) => v).onError((_, _) => null),
          ),
        ),
      );
    }
  }

  /// Spawns a Node.js process that loads the Dart test suite at [path].
  ///
  /// Returns that channel along with a [StackTraceMapper] representing the
  /// source map for the compiled suite.
  Future<(Process, StackTraceMapper?)> _spawnProcess(
    String path,
    SuitePlatform platform,
    SuiteConfiguration suiteConfig,
    int socketPort,
  ) async {
    if (_config.suiteDefaults.precompiledPath != null) {
      return _spawnPrecompiledProcess(
        path,
        platform.runtime,
        suiteConfig,
        socketPort,
        _config.suiteDefaults.precompiledPath!,
      );
    } else {
      return switch (platform.compiler) {
        Compiler.dart2js => _spawnNormalJsProcess(
          path,
          platform.runtime,
          suiteConfig,
          socketPort,
        ),
        Compiler.dart2wasm => _spawnNormalWasmProcess(
          path,
          platform.runtime,
          suiteConfig,
          socketPort,
        ),
        _ => throw StateError('Unsupported compiler ${platform.compiler}'),
      };
    }
  }

  Future<String> _entrypointScriptForTest(
    String testPath,
    SuiteConfiguration suiteConfig,
  ) async {
    return '''
        ${suiteConfig.metadata.languageVersionComment ?? await rootPackageLanguageVersionComment}
        import "package:test/src/bootstrap/node.dart";

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

        void main() {
          internalBootstrapNodeTest(() => test.main);
        }
      ''';
  }

  /// Compiles [testPath] with dart2js, adds the node preamble, and then spawns
  /// a Node.js process that loads that Dart test suite.
  Future<(Process, StackTraceMapper?)> _spawnNormalJsProcess(
    String testPath,
    Runtime runtime,
    SuiteConfiguration suiteConfig,
    int socketPort,
  ) async {
    var dir = Directory(_compiledDir).createTempSync('test_').path;
    var jsPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.js');
    await _jsCompilers.compile(
      await _entrypointScriptForTest(testPath, suiteConfig),
      jsPath,
      suiteConfig,
    );

    // Add the Node.js preamble to ensure that the dart2js output is
    // compatible. Use the minified version so the source map remains valid.
    var jsFile = File(jsPath);
    await jsFile.writeAsString(
      preamble.getPreamble(minified: true) + await jsFile.readAsString(),
    );

    StackTraceMapper? mapper;
    if (!suiteConfig.jsTrace) {
      var mapPath = '$jsPath.map';
      mapper = JSStackTraceMapper(
        await File(mapPath).readAsString(),
        mapUrl: p.toUri(mapPath),
        sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
        packageMap: (await currentPackageConfig).toPackageMap(),
      );
    }

    return (await _startProcess(runtime, jsPath, socketPort), mapper);
  }

  /// Compiles [testPath] with dart2wasm, adds a JS entrypoint and then spawns
  /// a Node.js process loading the compiled test suite.
  Future<(Process, StackTraceMapper?)> _spawnNormalWasmProcess(
    String testPath,
    Runtime runtime,
    SuiteConfiguration suiteConfig,
    int socketPort,
  ) async {
    var dir = Directory(_compiledDir).createTempSync('test_').path;
    // dart2wasm will emit a .wasm file and a .mjs file responsible for loading
    // that file.
    var wasmPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.wasm');
    var loader = '${p.basename(testPath)}.node_test.dart.wasm.mjs';

    // We need to create an additional entrypoint file loading the wasm module.
    var jsPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.js');

    await _wasmCompilers.compile(
      await _entrypointScriptForTest(testPath, suiteConfig),
      wasmPath,
      suiteConfig,
    );

    await File(jsPath).writeAsString('''
const { createReadStream } = require('fs');
const { once } = require('events');
const { PassThrough } = require('stream');

const main = async () => {
  const { instantiate, invoke } = await import("./$loader");

  const wasmContents = createReadStream(String.raw`$wasmPath.wasm`);
  const stream = new PassThrough();
  wasmContents.pipe(stream);

  await once(wasmContents, 'open');
  const response = new Response(
    stream,
    {
      headers: {
        "Content-Type": "application/wasm"
      }
    }
  );
  const instancePromise = WebAssembly.compileStreaming(response);
  const module = await instantiate(instancePromise, {});
  invoke(module);
};

main();
''');

    return (await _startProcess(runtime, jsPath, socketPort), null);
  }

  /// Spawns a Node.js process that loads the Dart test suite at [testPath]
  /// under [precompiledPath].
  Future<(Process, StackTraceMapper?)> _spawnPrecompiledProcess(
    String testPath,
    Runtime runtime,
    SuiteConfiguration suiteConfig,
    int socketPort,
    String precompiledPath,
  ) async {
    StackTraceMapper? mapper;
    var jsPath = p.join(precompiledPath, '$testPath.node_test.dart.js');
    if (!suiteConfig.jsTrace) {
      var mapPath = '$jsPath.map';
      mapper = JSStackTraceMapper(
        await File(mapPath).readAsString(),
        mapUrl: p.toUri(mapPath),
        sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
        packageMap: (await findPackageConfig(
          Directory(precompiledPath),
        ))!.toPackageMap(),
      );
    }

    return (await _startProcess(runtime, jsPath, socketPort), mapper);
  }

  /// Starts the Node.js process for [runtime] with [jsPath].
  Future<Process> _startProcess(
    Runtime runtime,
    String jsPath,
    int socketPort,
  ) async {
    var settings = _settings[runtime]!;

    var nodeModules = p.absolute('node_modules');
    var nodePath = Platform.environment['NODE_PATH'];
    nodePath = nodePath == null ? nodeModules : '$nodePath:$nodeModules';

    try {
      return await Process.start(
        settings.executable,
        settings.arguments.toList()
          ..add(jsPath)
          ..add(socketPort.toString()),
        environment: {'NODE_PATH': nodePath},
      );
    } catch (error, stackTrace) {
      await Future<Never>.error(
        ApplicationException(
          'Failed to run ${runtime.name}: ${getErrorMessage(error)}',
        ),
        stackTrace,
      );
    }
  }

  @override
  Future<void> close() => _closeMemo.runOnce(() async {
    await _jsCompilers.close();
    await _wasmCompilers.close();
    await Directory(_compiledDir).deleteWithRetry();
  });
  final _closeMemo = AsyncMemoizer<void>();
}

Future<List<ServerSocket>> _loopback({int remainingRetries = 5}) async {
  if (!await _supportsIPv4) {
    return [await ServerSocket.bind(InternetAddress.loopbackIPv6, 0)];
  }

  var v4Server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
  if (!await _supportsIPv6) return [v4Server];

  try {
    // Reuse the IPv4 server's port so that if [port] is 0, both servers use
    // the same ephemeral port.
    var v6Server = await ServerSocket.bind(
      InternetAddress.loopbackIPv6,
      v4Server.port,
    );
    return [v4Server, v6Server];
  } on SocketException catch (error) {
    if (error.osError?.errorCode != _addressInUseErrno) rethrow;
    if (remainingRetries == 0) rethrow;

    // A port being available on IPv4 doesn't necessarily mean that the same
    // port is available on IPv6. If it's not (which is rare in practice),
    // we try again until we find one that's available on both.
    unawaited(v4Server.close());
    return await _loopback(remainingRetries: remainingRetries - 1);
  }
}

/// Whether this computer supports binding to IPv6 addresses.
final Future<bool> _supportsIPv6 = () async {
  try {
    var socket = await ServerSocket.bind(InternetAddress.loopbackIPv6, 0);
    unawaited(socket.close());
    return true;
  } on SocketException catch (_) {
    return false;
  }
}();

/// Whether this computer supports binding to IPv4 addresses.
final Future<bool> _supportsIPv4 = () async {
  try {
    var socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
    unawaited(socket.close());
    return true;
  } on SocketException catch (_) {
    return false;
  }
}();

/// The error code for an error caused by a port already being in use.
final int _addressInUseErrno = () {
  if (Platform.isWindows) return 10048;
  if (Platform.isMacOS) return 48;
  assert(Platform.isLinux);
  return 98;
}();

/// A [StreamChannelTransformer] that converts a chunked string channel to a
/// line-by-line channel.
///
/// Note that this is only safe for channels whose messages are guaranteed not
/// to contain newlines.
final _chunksToLines = StreamChannelTransformer<String, String>(
  const LineSplitter(),
  StreamSinkTransformer.fromHandlers(
    handleData: (data, sink) => sink.add('$data\n'),
  ),
);
