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