// 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);
