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

import 'package:http_multi_server/http_multi_server.dart';
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_packages_handler/shelf_packages_handler.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:test_api/backend.dart' show StackTraceMapper, SuitePlatform;
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/package_version.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/suite.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:web_socket_channel/web_socket_channel.dart';

import '../../../util/math.dart';
import '../../../util/one_off_handler.dart';
import '../../../util/package_map.dart';
import '../../../util/path_handler.dart';
import 'compiler_support.dart';

/// Support for Dart2Js compiled tests.
class Dart2JsSupport extends CompilerSupport with JsHtmlWrapper {
  /// Whether [close] has been called.
  bool _closed = false;

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

  /// A map from test suite paths to Futures that will complete once those
  /// suites are finished compiling.
  ///
  /// This is used to make sure that a given test suite is only compiled once
  /// per run, rather than once per browser per run.
  final _compileFutures = <String, Future<void>>{};

  /// The [Dart2JsCompilerPool] managing active instances of `dart2js`.
  final _compilerPool = Dart2JsCompilerPool();

  /// Mappers for Dartifying stack traces, indexed by test path.
  final _mappers = <String, StackTraceMapper>{};

  /// A [PathHandler] used to serve test specific artifacts.
  final _pathHandler = PathHandler();

  /// The root directory served statically by this server.
  final String _root;

  /// Each compiler serves its tests under a different randomly-generated
  /// secret URI to ensure that other users on the same system can't snoop
  /// on data being served through this server, as well as distinguish tests
  /// from different compilers from each other.
  final String _secret = randomUrlSecret();

  /// The underlying server.
  final shelf.Server _server;

  /// A [OneOffHandler] for servicing WebSocket connections for
  /// [BrowserManager]s.
  ///
  /// This is one-off because each [BrowserManager] can only connect to a single
  /// WebSocket.
  final _webSocketHandler = OneOffHandler();

  @override
  Uri get serverUrl => _server.url.resolve('$_secret/');

  Dart2JsSupport._(
    super.config,
    super.defaultTemplatePath,
    this._server,
    this._root,
    String faviconPath,
  ) {
    var cascade = shelf.Cascade()
        .add(_webSocketHandler.handler)
        .add(packagesDirHandler())
        .add(_pathHandler.handler)
        .add(createStaticHandler(_root))
        .add(htmlWrapperHandler);

    var pipeline = const shelf.Pipeline()
        .addMiddleware(PathHandler.nestedIn(_secret))
        .addHandler(cascade.handler);

    _server.mount(
      shelf.Cascade().add(createFileHandler(faviconPath)).add(pipeline).handler,
    );
  }

  static Future<Dart2JsSupport> start({
    required Configuration config,
    required String defaultTemplatePath,
    required String root,
    required String faviconPath,
  }) async {
    var server = shelf_io.IOServer(await HttpMultiServer.loopback(0));
    return Dart2JsSupport._(
      config,
      defaultTemplatePath,
      server,
      root,
      faviconPath,
    );
  }

  @override
  Future<void> compileSuite(
    String dartPath,
    SuiteConfiguration suiteConfig,
    SuitePlatform platform,
  ) {
    return _compileFutures.putIfAbsent(dartPath, () async {
      var dir = Directory(_compiledDir).createTempSync('test_').path;
      var jsPath = p.join(dir, '${p.basename(dartPath)}.browser_test.dart.js');
      var bootstrapContent = '''
        ${suiteConfig.metadata.languageVersionComment ?? await rootPackageLanguageVersionComment}
        import 'dart:js_interop';
        import 'package:test/src/bootstrap/browser.dart';
        import 'package:test/src/runner/browser/dom.dart' as dom;

        import '${await absoluteUri(dartPath)}' as test;

        void main() {
          dom.window.console.log(r'Startup for test path $dartPath'.toJS);
          internalBootstrapBrowserTest(() => test.main);
        }
      ''';

      await _compilerPool.compile(bootstrapContent, jsPath, suiteConfig);
      if (_closed) return;

      var bootstrapUrl =
          '${p.toUri(p.relative(dartPath, from: _root)).path}'
          '.browser_test.dart';
      _pathHandler.add(bootstrapUrl, (request) {
        return shelf.Response.ok(
          bootstrapContent,
          headers: {'Content-Type': 'application/dart'},
        );
      });

      var jsUrl =
          '${p.toUri(p.relative(dartPath, from: _root)).path}'
          '.browser_test.dart.js';
      _pathHandler.add(jsUrl, (request) {
        return shelf.Response.ok(
          File(jsPath).readAsStringSync(),
          headers: {'Content-Type': 'application/javascript'},
        );
      });

      var mapUrl =
          '${p.toUri(p.relative(dartPath, from: _root)).path}'
          '.browser_test.dart.js.map';
      _pathHandler.add(mapUrl, (request) {
        return shelf.Response.ok(
          File('$jsPath.map').readAsStringSync(),
          headers: {'Content-Type': 'application/json'},
        );
      });

      if (suiteConfig.jsTrace) return;
      var mapPath = '$jsPath.map';
      _mappers[dartPath] = JSStackTraceMapper(
        File(mapPath).readAsStringSync(),
        mapUrl: p.toUri(mapPath),
        sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
        packageMap: (await currentPackageConfig).toPackageMap(),
      );
    });
  }

  @override
  Future<void> close() async {
    if (_closed) return;
    _closed = true;
    await Future.wait([
      Directory(_compiledDir).deleteWithRetry(),
      _compilerPool.close(),
      _server.close(),
    ]);
  }

  @override
  StackTraceMapper? stackTraceMapperForPath(String dartPath) =>
      _mappers[dartPath];

  @override
  (Uri, Future<WebSocketChannel>) get webSocket {
    var completer = Completer<WebSocketChannel>.sync();
    // Note: the WebSocketChannel type below is needed for compatibility with
    // package:shelf_web_socket v2.
    var path = _webSocketHandler.create(
      webSocketHandler((WebSocketChannel ws, _) {
        completer.complete(ws);
      }),
    );
    var webSocketUrl = serverUrl.replace(scheme: 'ws').resolve(path);
    return (webSocketUrl, completer.future);
  }
}
