// 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.

// ignore_for_file: implementation_imports

import 'dart:async';

import 'package:json_rpc_2/src/peer.dart' as json_rpc;
import 'package:meta/meta.dart';
import 'package:sse/src/server/sse_handler.dart';
import 'package:stream_channel/stream_channel.dart';

class LoggingMiddlewareSink<S> implements StreamSink<S> {
  LoggingMiddlewareSink(this.sink);

  @override
  void add(S event) {
    print('DevTools SSE response: $event');
    sink.add(event);
  }

  @override
  void addError(Object error, [StackTrace? stackTrace]) {
    print('DevTools SSE error response: $error');
    sink.addError(error);
  }

  @override
  Future addStream(Stream<S> stream) {
    return sink.addStream(stream);
  }

  @override
  Future close() => sink.close();

  @override
  Future get done => sink.done;

  final StreamSink sink;
}

/// A connection between a DevTools front-end app and the DevTools server.
///
/// see `packages/devtools_app/lib/src/server_connection.dart`.
class ClientManager {
  ClientManager({required this.requestNotificationPermissions});

  /// The timeout to wait for a ping when verifying a client is still
  /// responsive.
  ///
  /// Usually clients are removed from the set once they disconnect, but due
  /// to SSE timeouts (to handle proxies dropping connections) a client may
  /// appear connected for up to 30s after they disconnected.
  ///
  /// In cases where we need to know quickly if a client is active (for example
  /// when trying to reuse it), we will ping it and wait only this period to see
  /// if it responds before assuming it is not available.
  static const _clientResponsivenessTimeout = Duration(milliseconds: 500);

  /// Whether to immediately request notification permissions when a client connects.
  /// Otherwise permission will be requested only with the first notification.
  final bool requestNotificationPermissions;
  final List<DevToolsClient> _clients = [];

  void acceptClient(SseConnection connection, {bool enableLogging = false}) {
    final client = DevToolsClient.fromSSEConnection(
      connection,
      enableLogging,
    );
    if (requestNotificationPermissions) {
      client.enableNotifications();
    }
    _clients.add(client);
    connection.sink.done.then((_) => _clients.remove(client));
  }

  /// Finds an active DevTools instance that is not already connecting to
  /// a VM service that we can reuse (for example if a user stopped debugging
  /// and it disconnected, then started debugging again, we want to reuse
  /// the open DevTools window).
  ///
  /// Candidate clients will be pinged first to ensure they are responsive, to
  /// avoid trying to reuse a client that is in an SSE timeout where we don't
  /// know if it is refreshing or gone.
  Future<DevToolsClient?> findReusableClient() {
    final candidates =
        _clients.where((c) => !c.hasConnection && c.reusable).toList();

    return _firstResponsiveClient(candidates);
  }

  /// Finds a client that may already be connected to this VM Service.
  ///
  /// Candidate clients will be pinged first to ensure they are responsive, to
  /// avoid trying to reuse a client that is in an SSE timeout where we don't
  /// know if it is refreshing or gone.
  Future<DevToolsClient?> findExistingConnectedReusableClient(
      Uri vmServiceUri) {
    final candidates = _clients
        .where((c) =>
            c.hasConnection &&
            c.reusable &&
            _areSameVmServices(c.vmServiceUri!, vmServiceUri))
        .toList();

    return _firstResponsiveClient(candidates);
  }

  /// Pings [candidates] and returns the first one that responds.
  ///
  /// If no clients respond within a short period, returns `null` because all
  /// clients have likely been closed (but are in an SSE timeout period).
  Future<DevToolsClient?> _firstResponsiveClient(
      List<DevToolsClient> candidates) async {
    if (candidates.isEmpty) {
      return null;
    }
    // Use `Future.any` to get the first client that responds to its
    // ping.
    final firstRespondingClient = Future.any(
      candidates.cast<DevToolsClient?>().map((client) async {
        await client?.ping();
        return client;
      }),
    );

    final client = await firstRespondingClient.timeout(
      _clientResponsivenessTimeout,
      onTimeout: () => null,
    );

    return client;
  }

  @override
  String toString() {
    return _clients.map((c) {
      return '${c.hasConnection.toString().padRight(5)} '
          '${c.currentPage?.padRight(12)} ${c.vmServiceUri.toString()}';
    }).join('\n');
  }

  Map<String, dynamic> toJson(dynamic id) => {
        'id': id,
        'result': {
          'clients': _clients.map((e) => e.toJson()).toList(),
        }
      };

  /// Checks whether two VM Services are equivalent.
  ///
  /// Checking the whole URI will fail if DevTools converted it from HTTP to
  /// WS, so just checks the host, port and first segment of path (token).
  bool _areSameVmServices(Uri uri1, Uri uri2) {
    return uri1.host == uri2.host &&
        uri1.port == uri2.port &&
        uri1.pathSegments.isNotEmpty &&
        uri2.pathSegments.isNotEmpty &&
        uri1.pathSegments[0] == uri2.pathSegments[0];
  }
}

/// Represents a DevTools client connection to the DevTools server API.
class DevToolsClient {
  factory DevToolsClient.fromSSEConnection(
    SseConnection sse,
    bool loggingEnabled,
  ) {
    Stream<String> stream = sse.stream;
    StreamSink sink = sse.sink;
    return DevToolsClient(
      stream: stream,
      sink: sink,
      loggingEnabled: loggingEnabled,
    );
  }

  @visibleForTesting
  DevToolsClient({
    required Stream<String> stream,
    required StreamSink sink,
    bool loggingEnabled = false,
  }) {
    if (loggingEnabled) {
      stream = stream.map<String>((String e) {
        print('DevTools SSE request: $e');
        return e;
      });
      sink = LoggingMiddlewareSink<String>(sink);
    }

    _devToolsPeer = json_rpc.Peer(
      StreamChannel(stream, sink as StreamSink<String>),
      strictProtocolChecks: false,
    );
    _registerJsonRpcMethods();
    _devToolsPeer.listen();
  }

  void _registerJsonRpcMethods() {
    _devToolsPeer.registerMethod('connected', (parameters) {
      _vmServiceUri = Uri.parse(parameters['uri'].asString);
    });

    _devToolsPeer.registerMethod('disconnected', (parameters) {
      _vmServiceUri = null;
    });

    _devToolsPeer.registerMethod('currentPage', (parameters) {
      _initialized = true;
      _currentPage = parameters['id'].asString;
      _embedded = parameters['embedded'].asBool;
    });

    _devToolsPeer.registerMethod('pingResponse', (parameters) {
      _nextPingResponse.complete();
      _nextPingResponse = Completer();
    });
  }

  /// A completer that completes when the client next responds to a ping.
  ///
  /// See [ping].
  Completer<void> _nextPingResponse = Completer();

  /// Notify the DevTools client to connect to a specific VM service instance.
  void connectToVmService(Uri uri, bool notifyUser) {
    _devToolsPeer.sendNotification('connectToVm', {
      'uri': uri.toString(),
      'notify': notifyUser,
    });
  }

  void notify() => _devToolsPeer.sendNotification('notify');

  /// Pings the client and waits for it to respond.
  Future<void> ping() {
    _devToolsPeer.sendNotification('ping');
    return _nextPingResponse.future;
  }

  /// Enable notifications to the user from this DevTools client.
  void enableNotifications() =>
      _devToolsPeer.sendNotification('enableNotifications');

  /// Notify the DevTools client to show a specific page.
  void showPage(String pageId) {
    _devToolsPeer.sendNotification('showPage', {
      'page': pageId,
    });
  }

  Map<String, dynamic> toJson() => {
        'hasConnection': hasConnection,
        'currentPage': currentPage,
        'embedded': embedded,
        'vmServiceUri': vmServiceUri?.toString(),
      };

  /// Whether this client has initialized by sending a `currentPage` event to
  /// indicate a page has loaded.
  ///
  /// Until the currentPage has been received, we do not know if a client is
  /// embedded or not so we must not reuse any clients that are in this
  /// uninitialized state.
  bool get initialized => _initialized;
  bool _initialized = false;

  /// The current DevTools page displayed by this client.
  String? get currentPage => _currentPage;
  String? _currentPage;

  /// Returns true if this DevTools client is embedded.
  bool get embedded => _embedded;
  bool _embedded = false;

  /// Returns the VM service URI that the DevTools client is currently
  /// connected to. Returns null if the client is not connected to a process.
  Uri? get vmServiceUri => _vmServiceUri;
  Uri? _vmServiceUri;

  /// Whether this client can be reused when the user tries to navigate to a
  /// different DevTools page.
  bool get reusable => initialized && !embedded;

  bool get hasConnection => _vmServiceUri != null;

  late json_rpc.Peer _devToolsPeer;
}
