// Copyright (c) 2015, 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.

part of "dart:developer";

/// A response to a service protocol extension RPC.
///
/// If the RPC was successful, use [ServiceExtensionResponse.result], otherwise
/// use [ServiceExtensionResponse.error].
final class ServiceExtensionResponse {
  /// The result of a successful service protocol extension RPC.
  final String? result;

  /// The error code associated with a failed service protocol extension RPC.
  final int? errorCode;

  /// The details of a failed service protocol extension RPC.
  final String? errorDetail;

  /// Creates a successful response to a service protocol extension RPC.
  ///
  /// Requires [result] to be a JSON object encoded as a string. When forming
  /// the JSON-RPC message [result] will be inlined directly.
  ServiceExtensionResponse.result(String result)
    : result = result,
      errorCode = null,
      errorDetail = null;

  /// Creates an error response to a service protocol extension RPC.
  ///
  /// Requires [errorCode] to be [invalidParams] or between [extensionErrorMin]
  /// and [extensionErrorMax]. Requires [errorDetail] to be a JSON object
  /// encoded as a string. When forming the JSON-RPC message [errorDetail] will
  /// be inlined directly.
  ServiceExtensionResponse.error(int errorCode, String errorDetail)
    : result = null,
      errorCode = errorCode,
      errorDetail = errorDetail {
    _validateErrorCode(errorCode);
  }

  /// Invalid method parameter(s) error code.
  static const invalidParams = -32602;

  /// Generic extension error code.
  static const extensionError = -32000;

  /// Maximum extension provided error code.
  static const extensionErrorMax = -32000;

  /// Minimum extension provided error code.
  static const extensionErrorMin = -32016;

  static String _errorCodeMessage(int errorCode) {
    _validateErrorCode(errorCode);
    if (errorCode == invalidParams) {
      return "Invalid params";
    }
    return "Server error";
  }

  static _validateErrorCode(int errorCode) {
    if (errorCode == invalidParams) return;
    if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) {
      return;
    }
    throw new ArgumentError.value(errorCode, "errorCode", "Out of range");
  }

  /// Determines if this response represents an error.
  bool isError() => (errorCode != null) && (errorDetail != null);

  // ignore: unused_element, called from runtime/lib/developer.dart
  String _toString() {
    return result ??
        json.encode({
          'code': errorCode!,
          'message': _errorCodeMessage(errorCode!),
          'data': {'details': errorDetail!},
        });
  }
}

/// A service protocol extension handler. Registered with [registerExtension].
///
/// Must complete to a [ServiceExtensionResponse]. [method] is the method name
/// of the service protocol request, and [parameters] is a map holding the
/// parameters to the service protocol request.
///
/// *NOTE*: all parameter names and values are encoded as strings.
typedef Future<ServiceExtensionResponse> ServiceExtensionHandler(
  String method,
  Map<String, String> parameters,
);

/// Register a [ServiceExtensionHandler] that will be invoked in this isolate
/// for [method]. *NOTE*: Service protocol extensions must be registered
/// in each isolate.
///
/// *NOTE*: [method] must begin with 'ext.' and you should use the following
/// structure to avoid conflicts with other packages: 'ext.package.command'.
/// That is, immediately following the 'ext.' prefix, should be the registering
/// package name followed by another period ('.') and then the command name.
/// For example: 'ext.dart.io.getOpenFiles'.
///
/// Because service extensions are isolate specific, clients using extensions
/// must always include an 'isolateId' parameter with each RPC.
void registerExtension(String method, ServiceExtensionHandler handler) {
  if (!method.startsWith('ext.')) {
    throw new ArgumentError.value(method, 'method', 'Must begin with ext.');
  }
  if (_lookupExtension(method) != null) {
    throw new ArgumentError('Extension already registered: $method');
  }
  final zoneHandler = Zone.current.bindBinaryCallback(handler);
  _registerExtension(method, zoneHandler);
}

/// Whether the "Extension" stream currently has at least one listener.
///
/// A client of the VM service can register as a listener
/// on the extension stream using `listenStream` method.
/// The extension stream has a listener while at least one such
/// client has registered as a listener, and has not yet disconnected
/// again.
///
/// Calling [postEvent] while the stream has listeners will attempt to
/// deliver that event to all current listeners,
/// although a listener can disconnect before the event is delivered.
/// Calling [postEvent] when the stream has no listener means that
/// no-one will receive the event, and the call is effectively a no-op.
@pragma("vm:recognized", "other")
@pragma("vm:prefer-inline")
@pragma("vm:idempotent")
@Since('2.18')
external bool get extensionStreamHasListener;

/// Post an event of [eventKind] with payload of [eventData] to the "Extension"
/// event stream.
///
/// If [extensionStreamHasListener] is false, this method is a no-op.
/// Override [stream] to set the destination stream that the event should be
/// posted to. The [stream] may not start with an underscore or be a core VM
/// Service stream.
void postEvent(
  String eventKind,
  Map eventData, {
  @Since('3.0 ') String stream = 'Extension',
}) {
  const destinationStreamKey = '__destinationStream';
  // Keep protected streams in sync with `streams_` in runtime/vm/service.cc
  // `Extension` is the only stream that should not be protected here.
  final protectedStreams = <String>[
    'VM',
    'Isolate',
    'Debug',
    'GC',
    '_Echo',
    'HeapSnapshot',
    'Logging',
    'Timer',
    'Timeline',
    'Profiler',
  ];

  if (protectedStreams.contains(stream)) {
    throw ArgumentError.value(
      stream,
      'stream',
      'Cannot be a protected stream.',
    );
  } else if (stream.startsWith('_')) {
    throw ArgumentError.value(
      stream,
      'stream',
      'Cannot start with an underscore.',
    );
  }

  if (!extensionStreamHasListener) {
    return;
  }
  Map mutableEventData = Map.from(eventData); // Shallow copy.
  mutableEventData[destinationStreamKey] = stream;
  String eventDataAsString = json.encode(mutableEventData);
  _postEvent(eventKind, eventDataAsString);
}

external void _postEvent(String eventKind, String eventData);

// Both of these functions are written inside C++ to avoid updating the data
// structures in Dart, getting an OOB, and observing stale state. Do not move
// these into Dart code unless you can ensure that the operations will can be
// done atomically. Native code lives in vm/isolate.cc-
// LookupServiceExtensionHandler and RegisterServiceExtensionHandler.
external ServiceExtensionHandler? _lookupExtension(String method);
external _registerExtension(String method, ServiceExtensionHandler handler);
