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

/// Note: the VM concatenates all patch files into a single patch file. This
/// file is the first patch in "dart:developer" which contains all the imports
/// used by patches of that library. We plan to change this when we have a
/// shared front end and simply use parts.

import "dart:_internal" show patch;

import "dart:async" show Future, Zone;

import "dart:isolate" show SendPort;

/// These are the additional parts of this patch library:
// part "profiler.dart"
// part "timeline.dart"

@patch
bool debugger({bool when: true, String? message}) native "Developer_debugger";

@patch
Object? inspect(Object? object) native "Developer_inspect";

@patch
void log(String message,
    {DateTime? time,
    int? sequenceNumber,
    int level: 0,
    String name: '',
    Zone? zone,
    Object? error,
    StackTrace? stackTrace}) {
  if (message is! String) {
    throw new ArgumentError.value(message, "message", "Must be a String");
  }
  time ??= new DateTime.now();
  if (time is! DateTime) {
    throw new ArgumentError.value(time, "time", "Must be a DateTime");
  }
  if (sequenceNumber == null) {
    sequenceNumber = _nextSequenceNumber++;
  } else {
    _nextSequenceNumber = sequenceNumber + 1;
  }
  _log(message, time.millisecondsSinceEpoch, sequenceNumber, level, name, zone,
      error, stackTrace);
}

int _nextSequenceNumber = 0;

_log(String message, int timestamp, int sequenceNumber, int level, String name,
    Zone? zone, Object? error, StackTrace? stackTrace) native "Developer_log";

@patch
void _postEvent(String eventKind, String eventData)
    native "Developer_postEvent";

@patch
ServiceExtensionHandler? _lookupExtension(String method)
    native "Developer_lookupExtension";

@patch
_registerExtension(String method, ServiceExtensionHandler handler)
    native "Developer_registerExtension";

// This code is only invoked when there is no other Dart code on the stack.
@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
_runExtension(
    ServiceExtensionHandler handler,
    String method,
    List<String> parameterKeys,
    List<String> parameterValues,
    SendPort replyPort,
    Object id,
    bool trace_service) {
  var parameters = <String, String>{};
  for (var i = 0; i < parameterKeys.length; i++) {
    parameters[parameterKeys[i]] = parameterValues[i];
  }
  var response;
  try {
    response = handler(method, parameters);
  } catch (e, st) {
    var errorDetails = (st == null) ? '$e' : '$e\n$st';
    response = new ServiceExtensionResponse.error(
        ServiceExtensionResponse.kExtensionError, errorDetails);
    _postResponse(replyPort, id, response, trace_service);
    return;
  }
  if (response is! Future) {
    response = new ServiceExtensionResponse.error(
        ServiceExtensionResponse.kExtensionError,
        "Extension handler must return a Future");
    _postResponse(replyPort, id, response, trace_service);
    return;
  }
  response.catchError((e, st) {
    // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
    var errorDetails = (st == null) ? '$e' : '$e\n$st';
    return new ServiceExtensionResponse.error(
        ServiceExtensionResponse.kExtensionError, errorDetails);
  }).then((response) {
    // Post the valid response or the wrapped error after verifying that
    // the response is a ServiceExtensionResponse.
    if (response is! ServiceExtensionResponse) {
      response = new ServiceExtensionResponse.error(
          ServiceExtensionResponse.kExtensionError,
          "Extension handler must complete to a ServiceExtensionResponse");
    }
    _postResponse(replyPort, id, response, trace_service);
  }).catchError((e, st) {
    // We do not expect any errors to occur in the .then or .catchError blocks
    // but, suppress them just in case.
  });
}

// This code is only invoked by _runExtension.
_postResponse(SendPort replyPort, Object id, ServiceExtensionResponse response,
    bool trace_service) {
  assert(replyPort != null);
  if (id == null) {
    if (trace_service) {
      print("vm-service: posting no response for request");
    }
    // No id -> no response.
    replyPort.send(null);
    return;
  }
  assert(id != null);
  StringBuffer sb = new StringBuffer();
  sb.write('{"jsonrpc":"2.0",');
  if (response.isError()) {
    if (trace_service) {
      print("vm-service: posting error response for request $id");
    }
    sb.write('"error":');
  } else {
    if (trace_service) {
      print("vm-service: posting response for request $id");
    }
    sb.write('"result":');
  }
  sb.write('${response._toString()},');
  if (id is String) {
    sb.write('"id":"$id"}');
  } else {
    sb.write('"id":$id}');
  }
  replyPort.send(sb.toString());
}

@patch
int _getServiceMajorVersion() native "Developer_getServiceMajorVersion";

@patch
int _getServiceMinorVersion() native "Developer_getServiceMinorVersion";

@patch
void _getServerInfo(SendPort sendPort) native "Developer_getServerInfo";

@patch
void _webServerControl(SendPort sendPort, bool enable, bool? silenceOutput)
    native "Developer_webServerControl";

@patch
String _getIsolateIDFromSendPort(SendPort sendPort)
    native "Developer_getIsolateIDFromSendPort";
