// Copyright (c) 2022, 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 'package:dwds/data/build_result.dart';
import 'package:dwds/src/config/tool_configuration.dart';
import 'package:dwds/src/connections/app_connection.dart';
import 'package:dwds/src/connections/debug_connection.dart';
import 'package:dwds/src/events.dart';
import 'package:dwds/src/handlers/dev_handler.dart';
import 'package:dwds/src/handlers/injector.dart';
import 'package:dwds/src/handlers/socket_connections.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/servers/devtools.dart';
import 'package:dwds/src/servers/extension_backend.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
import 'package:sse/server/sse_handler.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

typedef ConnectionProvider = Future<ChromeConnection> Function();

/// The Dart Web Debug Service.
class Dwds {
  static final _logger = Logger('DWDS');
  final Middleware middleware;
  final Handler handler;
  final DevTools? _devTools;
  final DevHandler _devHandler;
  final AssetReader _assetReader;
  final bool _enableDebugging;
  final bool _useDwdsWebSocketConnection;

  Dwds._(
    this.middleware,
    this._devTools,
    this._devHandler,
    this._assetReader,
    this._enableDebugging,
    this._useDwdsWebSocketConnection,
  ) : handler = _devHandler.handler;

  Stream<AppConnection> get connectedApps => _devHandler.connectedApps;

  Stream<DwdsEvent> get events => eventStream;

  StreamController<DebugConnection> get extensionDebugConnections =>
      _devHandler.extensionDebugConnections;

  Future<void> stop() async {
    await _devTools?.close();
    await _devHandler.close();
    await _assetReader.close();
  }

  /// Creates a debug connection for the given app connection.
  ///
  /// Returns a [DebugConnection] that wraps the appropriate debug services
  /// based on the connection type (WebSocket or Chrome-based).
  Future<DebugConnection> debugConnection(AppConnection appConnection) async {
    if (!_enableDebugging) throw StateError('Debugging is not enabled.');

    if (_useDwdsWebSocketConnection) {
      return await _devHandler.createDebugConnectionForWebSocket(appConnection);
    } else {
      return await _devHandler.createDebugConnectionForChrome(appConnection);
    }
  }

  static Future<Dwds> start({
    required AssetReader assetReader,
    required Stream<BuildResult> buildResults,
    required ConnectionProvider chromeConnection,
    required ToolConfiguration toolConfiguration,
    bool useDwdsWebSocketConnection = false,
  }) async {
    globalToolConfiguration = toolConfiguration;
    final debugSettings = toolConfiguration.debugSettings;
    final appMetadata = toolConfiguration.appMetadata;
    DevTools? devTools;
    Future<String>? extensionUri;
    ExtensionBackend? extensionBackend;
    if (debugSettings.enableDebugExtension) {
      final handler =
          debugSettings.useSseForDebugBackend
              ? SseSocketHandler(
                SseHandler(
                  Uri.parse('/\$debug'),
                  // Proxy servers may actively kill long standing connections.
                  // Allow for clients to reconnect in a short window. Making the
                  // window too long may cause issues if the user closes a debug
                  // session and initiates a new one during the keepAlive window.
                  keepAlive: const Duration(seconds: 5),
                ),
              )
              : WebSocketSocketHandler();

      extensionBackend = await ExtensionBackend.start(
        handler,
        appMetadata.hostname,
      );
      extensionUri = Future.value(
        Uri(
          scheme: debugSettings.useSseForDebugBackend ? 'http' : 'ws',
          host: extensionBackend.hostname,
          port: extensionBackend.port,
          path: r'$debug',
        ).toString(),
      );
      final urlEncoder = debugSettings.urlEncoder;
      if (urlEncoder != null) {
        extensionUri = urlEncoder(await extensionUri);
      }
    }

    final devToolsLauncher = debugSettings.devToolsLauncher;
    if (devToolsLauncher != null) {
      devTools = await devToolsLauncher(appMetadata.hostname);
      final uri = Uri(
        scheme: 'http',
        host: devTools.hostname,
        port: devTools.port,
      );
      _logger.info('Serving DevTools at $uri\n');
    }

    final injected = DwdsInjector(extensionUri: extensionUri);

    final devHandler = DevHandler(
      chromeConnection,
      buildResults,
      devTools,
      assetReader,
      appMetadata.hostname,
      extensionBackend,
      debugSettings.urlEncoder,
      debugSettings.useSseForDebugProxy,
      debugSettings.useSseForInjectedClient,
      debugSettings.expressionCompiler,
      injected,
      debugSettings.spawnDds,
      debugSettings.ddsPort,
      debugSettings.launchDevToolsInNewWindow,
      useWebSocketConnection: useDwdsWebSocketConnection,
    );

    return Dwds._(
      injected.middleware,
      devTools,
      devHandler,
      assetReader,
      debugSettings.enableDebugging,
      useDwdsWebSocketConnection,
    );
  }
}
