// Copyright (c) 2014, 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:collection';
import 'dart:convert';

import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';

import '../error_code.dart' as error_code;
import 'exception.dart';
import 'parameters.dart';
import 'utils.dart';

/// A callback for unhandled exceptions.
typedef ErrorCallback = void Function(dynamic error, dynamic stackTrace);

/// A JSON-RPC 2.0 server.
///
/// A server exposes methods that are called by requests, to which it provides
/// responses. Methods can be registered using [registerMethod] and
/// [registerFallback]. Requests can be handled using [handleRequest] and
/// [parseRequest].
///
/// Note that since requests can arrive asynchronously and methods can run
/// asynchronously, it's possible for multiple methods to be invoked at the same
/// time, or even for a single method to be invoked multiple times at once.
class Server {
  final StreamChannel<dynamic> _channel;

  /// The methods registered for this server.
  final _methods = <String, Function>{};

  /// The fallback methods for this server.
  ///
  /// These are tried in order until one of them doesn't throw a
  /// [RpcException.methodNotFound] exception.
  final _fallbacks = Queue<Function>();

  final _done = Completer<void>();

  /// Returns a [Future] that completes when the underlying connection is
  /// closed.
  ///
  /// This is the same future that's returned by [listen] and [close]. It may
  /// complete before [close] is called if the remote endpoint closes the
  /// connection.
  Future get done => _done.future;

  /// Whether the underlying connection is closed.
  ///
  /// Note that this will be `true` before [close] is called if the remote
  /// endpoint closes the connection.
  bool get isClosed => _done.isCompleted;

  /// A callback that is fired on unhandled exceptions.
  ///
  /// In the case where a user provided callback results in an exception that
  /// cannot be properly routed back to the client, this handler will be
  /// invoked. If it is not set, the exception will be swallowed.
  final ErrorCallback? onUnhandledError;

  /// Whether to strictly enforce the JSON-RPC 2.0 specification for received
  /// messages.
  ///
  /// If `false`, this [Server] will accept some requests which are not
  /// conformant with the JSON-RPC 2.0 specification. In particular, requests
  /// missing the `jsonrpc` parameter will be accepted.
  final bool strictProtocolChecks;

  /// Creates a [Server] that communicates over [channel].
  ///
  /// Note that the server won't begin listening to [requests] until
  /// [Server.listen] is called.
  ///
  /// Unhandled exceptions in callbacks will be forwarded to [onUnhandledError].
  /// If this is not provided, unhandled exceptions will be swallowed.
  ///
  /// If [strictProtocolChecks] is false, this [Server] will accept some
  /// requests which are not conformant with the JSON-RPC 2.0 specification. In
  /// particular, requests missing the `jsonrpc` parameter will be accepted.
  Server(StreamChannel<String> channel,
      {ErrorCallback? onUnhandledError, bool strictProtocolChecks = true})
      : this.withoutJson(
            jsonDocument.bind(channel).transform(respondToFormatExceptions),
            onUnhandledError: onUnhandledError,
            strictProtocolChecks: strictProtocolChecks);

  /// Creates a [Server] that communicates using decoded messages over
  /// [channel].
  ///
  /// Unlike [new Server], this doesn't read or write JSON strings. Instead, it
  /// reads and writes decoded maps or lists.
  ///
  /// Note that the server won't begin listening to [requests] until
  /// [Server.listen] is called.
  ///
  /// Unhandled exceptions in callbacks will be forwarded to [onUnhandledError].
  /// If this is not provided, unhandled exceptions will be swallowed.
  ///
  /// If [strictProtocolChecks] is false, this [Server] will accept some
  /// requests which are not conformant with the JSON-RPC 2.0 specification. In
  /// particular, requests missing the `jsonrpc` parameter will be accepted.
  Server.withoutJson(this._channel,
      {this.onUnhandledError, this.strictProtocolChecks = true});

  /// Starts listening to the underlying stream.
  ///
  /// Returns a [Future] that will complete when the connection is closed or
  /// when it has an error. This is the same as [done].
  ///
  /// [listen] may only be called once.
  Future listen() {
    _channel.stream.listen(_handleRequest, onError: (error, stackTrace) {
      _done.completeError(error, stackTrace);
      _channel.sink.close();
    }, onDone: () {
      if (!_done.isCompleted) _done.complete();
    });
    return done;
  }

  /// Closes the underlying connection.
  ///
  /// Returns a [Future] that completes when all resources have been released.
  /// This is the same as [done].
  Future close() {
    _channel.sink.close();
    if (!_done.isCompleted) _done.complete();
    return done;
  }

  /// Registers a method named [name] on this server.
  ///
  /// [callback] can take either zero or one arguments. If it takes zero, any
  /// requests for that method that include parameters will be rejected. If it
  /// takes one, it will be passed a [Parameters] object.
  ///
  /// [callback] can return either a JSON-serializable object or a Future that
  /// completes to a JSON-serializable object. Any errors in [callback] will be
  /// reported to the client as JSON-RPC 2.0 errors.
  void registerMethod(String name, Function callback) {
    if (_methods.containsKey(name)) {
      throw ArgumentError('There\'s already a method named "$name".');
    }

    _methods[name] = callback;
  }

  /// Registers a fallback method on this server.
  ///
  /// A server may have any number of fallback methods. When a request comes in
  /// that doesn't match any named methods, each fallback is tried in order. A
  /// fallback can pass on handling a request by throwing a
  /// [RpcException.methodNotFound] exception.
  ///
  /// [callback] can return either a JSON-serializable object or a Future that
  /// completes to a JSON-serializable object. Any errors in [callback] will be
  /// reported to the client as JSON-RPC 2.0 errors. [callback] may send custom
  /// errors by throwing an [RpcException].
  void registerFallback(Function(Parameters parameters) callback) {
    _fallbacks.add(callback);
  }

  /// Handle a request.
  ///
  /// [request] is expected to be a JSON-serializable object representing a
  /// request sent by a client. This calls the appropriate method or methods for
  /// handling that request and returns a JSON-serializable response, or `null`
  /// if no response should be sent. [callback] may send custom
  /// errors by throwing an [RpcException].
  Future _handleRequest(request) async {
    var response;
    if (request is List) {
      if (request.isEmpty) {
        response = RpcException(error_code.INVALID_REQUEST,
                'A batch must contain at least one request.')
            .serialize(request);
      } else {
        var results = await Future.wait(request.map(_handleSingleRequest));
        var nonNull = results.where((result) => result != null);
        if (nonNull.isEmpty) return;
        response = nonNull.toList();
      }
    } else {
      response = await _handleSingleRequest(request);
      if (response == null) return;
    }

    if (!isClosed) _channel.sink.add(response);
  }

  /// Handles an individual parsed request.
  Future _handleSingleRequest(request) async {
    try {
      _validateRequest(request);

      var name = request['method'];
      var method = _methods[name];
      method ??= _tryFallbacks;

      Object result;
      if (method is ZeroArgumentFunction) {
        if (request.containsKey('params')) {
          throw RpcException.invalidParams('No parameters are allowed for '
              'method "$name".');
        }
        result = await method();
      } else {
        result = await method(Parameters(name, request['params']));
      }

      // A request without an id is a notification, which should not be sent a
      // response, even if one is generated on the server.
      if (!request.containsKey('id')) return null;

      return {'jsonrpc': '2.0', 'result': result, 'id': request['id']};
    } catch (error, stackTrace) {
      if (error is RpcException) {
        if (error.code == error_code.INVALID_REQUEST ||
            request.containsKey('id')) {
          return error.serialize(request);
        } else {
          onUnhandledError?.call(error, stackTrace);
          return null;
        }
      } else if (!request.containsKey('id')) {
        onUnhandledError?.call(error, stackTrace);
        return null;
      }
      final chain = Chain.forTrace(stackTrace);
      return RpcException(error_code.SERVER_ERROR, getErrorMessage(error),
          data: {
            'full': '$error',
            'stack': '$chain',
          }).serialize(request);
    }
  }

  /// Validates that [request] matches the JSON-RPC spec.
  void _validateRequest(request) {
    if (request is! Map) {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Request must be '
          'an Array or an Object.');
    }

    if (strictProtocolChecks && !request.containsKey('jsonrpc')) {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Request must '
          'contain a "jsonrpc" key.');
    }

    if ((strictProtocolChecks || request.containsKey('jsonrpc')) &&
        request['jsonrpc'] != '2.0') {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Invalid JSON-RPC '
          'version ${jsonEncode(request['jsonrpc'])}, expected "2.0".');
    }

    if (!request.containsKey('method')) {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Request must '
          'contain a "method" key.');
    }

    var method = request['method'];
    if (request['method'] is! String) {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Request method must '
          'be a string, but was ${jsonEncode(method)}.');
    }

    if (request.containsKey('params')) {
      var params = request['params'];
      if (params is! List && params is! Map) {
        throw RpcException(
            error_code.INVALID_REQUEST,
            'Request params must '
            'be an Array or an Object, but was ${jsonEncode(params)}.');
      }
    }

    var id = request['id'];
    if (id != null && id is! String && id is! num) {
      throw RpcException(
          error_code.INVALID_REQUEST,
          'Request id must be a '
          'string, number, or null, but was ${jsonEncode(id)}.');
    }
  }

  /// Try all the fallback methods in order.
  Future _tryFallbacks(Parameters params) {
    var iterator = _fallbacks.toList().iterator;

    Future _tryNext() async {
      if (!iterator.moveNext()) {
        throw RpcException.methodNotFound(params.method);
      }

      try {
        return await iterator.current(params);
      } on RpcException catch (error) {
        if (error is! RpcException) rethrow;
        if (error.code != error_code.METHOD_NOT_FOUND) rethrow;
        return _tryNext();
      }
    }

    return _tryNext();
  }
}
