// Copyright (c) 2020, 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:async/async.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:sse/server/sse_handler.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

/// An individual (transport-agnostic) bidirectional socket connection.
abstract class SocketConnection {
  /// Whether this connection is currently in the KeepAlive timeout period.
  bool get isInKeepAlivePeriod;

  /// Messages added to the sink must be JSON encodable.
  StreamSink<dynamic> get sink;

  Stream<String> get stream;

  /// Immediately close the connection, ignoring any keepAlive period.
  void shutdown();
}

/// A handler that accepts (transport-agnostic) bidirectional socket connections.
abstract class SocketHandler {
  StreamQueue<SocketConnection> get connections;
  FutureOr<Response> handler(Request request);
  void shutdown();
}

/// An implementation of [SocketConnection] that users server-sent events (SSE)
/// and HTTP POSTS for bidirectional communication by wrapping an [SseConnection].
class SseSocketConnection extends SocketConnection {
  final SseConnection _connection;

  SseSocketConnection(this._connection);

  @override
  bool get isInKeepAlivePeriod => _connection.isInKeepAlivePeriod;
  @override
  StreamSink<dynamic> get sink => _connection.sink;
  @override
  Stream<String> get stream => _connection.stream;
  @override
  void shutdown() => _connection.shutdown();
}

/// An implementation of [SocketHandler] that accepts server-sent events (SSE)
/// connections and wraps them in an [SseSocketConnection].
class SseSocketHandler extends SocketHandler {
  final SseHandler _sseHandler;
  final StreamController<SseSocketConnection> _connectionsStream =
      StreamController<SseSocketConnection>();
  StreamQueue<SseSocketConnection>? _connectionsStreamQueue;

  SseSocketHandler(this._sseHandler) {
    unawaited(() async {
      final injectedConnections = _sseHandler.connections;
      while (await injectedConnections.hasNext) {
        _connectionsStream.add(
          SseSocketConnection(await injectedConnections.next),
        );
      }
    }());
  }

  @override
  StreamQueue<SseSocketConnection> get connections =>
      _connectionsStreamQueue ??= StreamQueue(_connectionsStream.stream);
  @override
  FutureOr<Response> handler(Request request) => _sseHandler.handler(request);
  @override
  void shutdown() => _sseHandler.shutdown();
}

/// An implementation of [SocketConnection] that uses WebSockets for communication
/// by wrapping [WebSocketChannel].
class WebSocketConnection extends SocketConnection {
  final WebSocketChannel _channel;
  WebSocketConnection(this._channel);

  @override
  bool get isInKeepAlivePeriod => false;

  @override
  StreamSink<dynamic> get sink => _channel.sink;

  @override
  Stream<String> get stream => _channel.stream.map((dynamic o) => o.toString());

  @override
  void shutdown() => _channel.sink.close();
}

/// An implementation of [SocketHandler] that accepts WebSocket connections and
/// wraps them in a [WebSocketConnection].
class WebSocketSocketHandler extends SocketHandler {
  late Handler _handler;
  final StreamController<WebSocketConnection> _connectionsStream =
      StreamController<WebSocketConnection>();
  StreamQueue<WebSocketConnection>? _connectionsStreamQueue;

  WebSocketSocketHandler() {
    _handler = webSocketHandler(
      (WebSocketChannel channel, _) =>
          _connectionsStream.add(WebSocketConnection(channel)),
    );
  }

  @override
  StreamQueue<WebSocketConnection> get connections =>
      _connectionsStreamQueue ??= StreamQueue(_connectionsStream.stream);

  @override
  FutureOr<Response> handler(Request request) => _handler(request);

  @override
  void shutdown() {}
}
