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