// 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 Compiler, StackTraceMapper, SuitePlatform;
import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/suite.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';

class JsPrecompiledSupport = PrecompiledSupport with JsHtmlWrapper;
class WasmPrecompiledSupport = PrecompiledSupport with WasmHtmlWrapper;

/// Support for precompiled test files.
abstract class PrecompiledSupport extends CompilerSupport {
  /// Whether [close] has been called.
  bool _closed = false;

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

  /// The root directory served statically by the 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();

  /// The URL at which this compiler serves its tests.
  ///
  /// Each compiler serves its tests under a different directory.
  @override
  Uri get serverUrl => _server.url.resolve('$_secret/');

  PrecompiledSupport._(
    super.config,
    super.defaultTemplatePath,
    this._server,
    this._root,
    String faviconPath,
  ) {
    var cascade = shelf.Cascade()
        .add(_webSocketHandler.handler)
        .add(createStaticHandler(_root, serveFilesOutsidePath: true))
        // TODO: This packages dir handler should not be necessary?
        .add(packagesDirHandler())
        // Even for precompiled tests, we will auto-create a bootstrap html file
        // if none was present.
        .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<PrecompiledSupport> start({
    required Compiler compiler,
    required Configuration config,
    required String defaultTemplatePath,
    required String root,
    required String faviconPath,
  }) async {
    var server = shelf_io.IOServer(await HttpMultiServer.loopback(0));

    return switch (compiler) {
      Compiler.dart2js => JsPrecompiledSupport._(
        config,
        defaultTemplatePath,
        server,
        root,
        faviconPath,
      ),
      Compiler.dart2wasm => WasmPrecompiledSupport._(
        config,
        defaultTemplatePath,
        server,
        root,
        faviconPath,
      ),
      Compiler.exe ||
      Compiler.kernel ||
      Compiler.source => throw UnsupportedError(
        'The browser platform does not support $compiler',
      ),
    };
  }

  /// Compiles [dartPath] using [suiteConfig] for [platform].
  @override
  Future<void> compileSuite(
    String dartPath,
    SuiteConfiguration suiteConfig,
    SuitePlatform platform,
  ) async {
    if (suiteConfig.jsTrace) return;
    var mapPath = p.join(
      suiteConfig.precompiledPath!,
      '$dartPath.browser_test.dart.js.map',
    );
    var mapFile = File(mapPath);
    if (mapFile.existsSync()) {
      _mappers[dartPath] = JSStackTraceMapper(
        mapFile.readAsStringSync(),
        mapUrl: p.toUri(mapPath),
        sdkRoot: Uri.parse(r'/packages/$sdk'),
        packageMap: (await currentPackageConfig).toPackageMap(),
      );
    }
  }

  /// Retrieves a stack trace mapper for [path] if available.
  @override
  StackTraceMapper? stackTraceMapperForPath(String dartPath) =>
      _mappers[dartPath];

  /// Closes down anything necessary for this implementation.
  @override
  Future<void> close() async {
    if (_closed) return;
    _closed = true;
    await _server.close();
  }

  @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);
  }
}
