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

// Patch file for dart:developer library.

import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes;
import 'dart:_foreign_helper' show JS, JSExportName;
import 'dart:_runtime' as dart;
import 'dart:async';
import 'dart:convert' show json;
import 'dart:isolate';

var _issuedRegisterExtensionWarning = false;
final _developerSupportWarning = 'from dart:developer is only supported in '
    'build/run/test environments where the developer event method hooks have '
    'been set by package:dwds v11.1.0 or higher.';

/// Returns `true` if the debugger service has been attached to the app.
// TODO(46377) Update this check when we have a documented API for DDC apps.
bool get _debuggerAttached => JS<bool>('!', r'!!#.$dwdsVersion', dart.global_);

@patch
@ForceInline()
bool debugger({bool when = true, String? message}) {
  if (when) {
    JS('', 'debugger');
  }
  return when;
}

@patch
Object? inspect(Object? object) {
  // Note: this log level does not show up by default in Chrome.
  // This is used for communication with the debugger service.
  JS('', 'console.debug("dart.developer.inspect", #)', object);
  return object;
}

@patch
void log(String message,
    {DateTime? time,
    int? sequenceNumber,
    int level = 0,
    String name = '',
    Zone? zone,
    Object? error,
    StackTrace? stackTrace}) {
  Object items =
      JS('!', '{ message: #, name: #, level: # }', message, name, level);
  if (time != null) JS('', '#.time = #', items, time);
  if (sequenceNumber != null) {
    JS('', '#.sequenceNumber = #', items, sequenceNumber);
  }
  if (zone != null) JS('', '#.zone = #', items, zone);
  if (error != null) JS('', '#.error = #', items, error);
  if (stackTrace != null) JS('', '#.stackTrace = #', items, stackTrace);

  JS('', 'console.debug("dart.developer.log", #)', items);
}

final _extensions = <String, ServiceExtensionHandler>{};

@patch
ServiceExtensionHandler? _lookupExtension(String method) {
  return _extensions[method];
}

@patch
_registerExtension(String method, ServiceExtensionHandler handler) {
  if (!_debuggerAttached) {
    if (!_issuedRegisterExtensionWarning) {
      var message = 'registerExtension() $_developerSupportWarning';
      JS('', 'console.warn(#)', message);
      _issuedRegisterExtensionWarning = true;
    }
    return;
  }
  // TODO(46377) Update this check when we have a documented API for DDC apps.
  if (JS<bool>('!', r'!!#.$emitRegisterEvent', dart.global_)) {
    _extensions[method] = handler;
    // See hooks assigned by package:dwds:
    // https://github.com/dart-lang/webdev/blob/de05cf9fbbfe088be74bb61df4a138289a94d902/dwds/web/client.dart#L223
    JS('', r'#.$emitRegisterEvent(#)', dart.global_, method);
    return;
  }
  // TODO(48103) Remove use of debug log in Dart 3.0.0.
  JS('', 'console.debug("dart.developer.registerExtension", #)', method);
}

/// Returns a JS `Promise` that resolves with the result of invoking
/// [methodName] with an [encodedJson] map as its parameters.
///
/// This is used by the VM Service Prototcol to invoke extensions registered
/// with [registerExtension]. For example, in JS:
///
///     await sdk.developer.invokeExtension(
/// .         "ext.flutter.inspector.getRootWidget", '{"objectGroup":""}');
///
@JSExportName('invokeExtension')
@ReifyFunctionTypes(false)
_invokeExtension(String methodName, String encodedJson) {
  // TODO(vsm): We should factor this out as future<->promise.
  return JS('', 'new #.Promise(#)', dart.global_,
      (Function(Object) resolve, Function(Object) reject) async {
    try {
      var method = _lookupExtension(methodName)!;
      var parameters = (json.decode(encodedJson) as Map).cast<String, String>();
      var result = await method(methodName, parameters);
      resolve(result._toString());
    } catch (e) {
      // TODO(vsm): Reject or encode in result?
      reject('$e');
    }
  });
}

@patch
bool get extensionStreamHasListener => _debuggerAttached;

@patch
void _postEvent(String eventKind, String eventData) {
  // TODO(46377) Update this check when we have a documented API for DDC apps.
  if (JS<bool>('!', r'!!#.$emitDebugEvent', dart.global_)) {
    // See hooks assigned by package:dwds:
    // https://github.com/dart-lang/webdev/blob/de05cf9fbbfe088be74bb61df4a138289a94d902/dwds/web/client.dart#L220
    JS('', r'#.$emitDebugEvent(#, #)', dart.global_, eventKind, eventData);
    return;
  }
  // TODO(48103) Remove use of debug log in Dart 3.0.0.
  JS('', 'console.debug("dart.developer.postEvent", #, #)', eventKind,
      eventData);
}

@patch
bool _isDartStreamEnabled() {
  return false;
}

@patch
int _getTraceClock() {
  // TODO.
  return _clockValue++;
}

int _clockValue = 0;

@patch
void _reportFlowEvent(
    String category, String name, int type, int id, String argumentsAsJson) {
  // TODO.
}

@patch
void _reportInstantEvent(String category, String name, String argumentsAsJson) {
  // TODO.
}

@patch
int _getNextAsyncId() {
  return 0;
}

@patch
void _reportTaskEvent(int taskId, String phase, String category, String name,
    String argumentsAsJson) {
  // TODO.
}

@patch
int _getServiceMajorVersion() {
  return 0;
}

@patch
int _getServiceMinorVersion() {
  return 0;
}

@patch
void _getServerInfo(SendPort sendPort) {
  sendPort.send(null);
}

@patch
void _webServerControl(SendPort sendPort, bool enable, bool? silenceOutput) {
  sendPort.send(null);
}

@patch
String? _getIsolateIDFromSendPort(SendPort sendPort) {
  return null;
}

@patch
class UserTag {
  @patch
  factory UserTag(String label) = _FakeUserTag;

  @patch
  static UserTag get defaultTag => _FakeUserTag._defaultTag;
}

class _FakeUserTag implements UserTag {
  static final _instances = <String, _FakeUserTag>{};

  _FakeUserTag.real(this.label);

  factory _FakeUserTag(String label) {
    // Canonicalize by name.
    var existingTag = _instances[label];
    if (existingTag != null) {
      return existingTag;
    }
    // Throw an exception if we've reached the maximum number of user tags.
    if (_instances.length == UserTag.MAX_USER_TAGS) {
      throw UnsupportedError(
          'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
    }
    return _instances[label] = _FakeUserTag.real(label);
  }

  final String label;

  UserTag makeCurrent() {
    var old = _currentTag;
    _currentTag = this;
    return old;
  }

  static final UserTag _defaultTag = _FakeUserTag('Default');
}

var _currentTag = _FakeUserTag._defaultTag;

@patch
UserTag getCurrentTag() => _currentTag;
