// Copyright (c) 2019, 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:math' as math;

import 'package:async/async.dart';
import 'package:collection/collection.dart';
import 'package:dwds/src/config/tool_configuration.dart';
import 'package:dwds/src/connections/app_connection.dart';
import 'package:dwds/src/debugging/classes.dart';
import 'package:dwds/src/debugging/debugger.dart';
import 'package:dwds/src/debugging/execution_context.dart';
import 'package:dwds/src/debugging/instance.dart';
import 'package:dwds/src/debugging/libraries.dart';
import 'package:dwds/src/debugging/location.dart';
import 'package:dwds/src/debugging/remote_debugger.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/utilities/conversions.dart';
import 'package:dwds/src/utilities/dart_uri.dart';
import 'package:dwds/src/utilities/domain.dart';
import 'package:dwds/src/utilities/objects.dart';
import 'package:dwds/src/utilities/server.dart';
import 'package:dwds/src/utilities/shared.dart';
import 'package:logging/logging.dart';
import 'package:vm_service/vm_service.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';

/// An inspector for a running Dart application contained in the
/// [WipConnection].
///
/// Provides information about currently loaded scripts and objects and support
/// for eval.
class AppInspector implements AppInspectorInterface {
  final _scriptCacheMemoizer = AsyncMemoizer<List<ScriptRef>>();

  Future<List<ScriptRef>> get scriptRefs => _populateScriptCaches();

  final _logger = Logger('AppInspector');

  /// Map of scriptRef ID to [ScriptRef].
  final _scriptRefsById = <String, ScriptRef>{};

  /// Map of Dart server path to [ScriptRef].
  final _serverPathToScriptRef = <String, ScriptRef>{};

  /// Map of [ScriptRef] id to containing [LibraryRef] id.
  final _scriptIdToLibraryId = <String, String>{};

  /// Map of [Library] id to included [ScriptRef]s.
  final _libraryIdToScriptRefs = <String, List<ScriptRef>>{};

  @override
  RemoteDebugger get remoteDebugger => _remoteDebugger;
  final RemoteDebugger _remoteDebugger;

  @override
  Isolate get isolate => _isolate;
  final Isolate _isolate;

  @override
  IsolateRef get isolateRef => _isolateRef;
  final IsolateRef _isolateRef;

  @override
  AppConnection get appConnection => _appConnection;
  final AppConnection _appConnection;

  final ExecutionContext _executionContext;

  late final LibraryHelper _libraryHelper;
  late final ClassHelper _classHelper;
  late final InstanceHelper _instanceHelper;

  final AssetReader _assetReader;
  final Locations _locations;

  /// The root URI from which the application is served.
  final String _root;

  /// JavaScript expression that evaluates to the Dart stack trace mapper.
  static const stackTraceMapperExpression = '\$dartStackTraceUtility.mapper';

  /// Regex used to extract the message from an exception description.
  static final exceptionMessageRegex = RegExp(r'^.*$', multiLine: true);

  /// Flutter widget inspector library.
  Future<LibraryRef?> get flutterWidgetInspectorLibrary => _libraryHelper
      .libraryRefFor('package:flutter/src/widgets/widget_inspector.dart');

  /// Regex used to extract a stack trace line from the exception description.
  static final stackTraceLineRegex = RegExp(r'^\s*at\s.*$', multiLine: true);

  AppInspector._(
    this._appConnection,
    this._isolate,
    this._remoteDebugger,
    this._assetReader,
    this._locations,
    this._root,
    this._executionContext,
  ) : _isolateRef = _toIsolateRef(_isolate) {
    _libraryHelper = LibraryHelper(this);
    _classHelper = ClassHelper(this);
    _instanceHelper = InstanceHelper(this);
  }

  Future<void> initialize() async {
    final libraries = await _libraryHelper.libraryRefs;
    isolate.rootLib = await _libraryHelper.rootLib;
    isolate.libraries?.addAll(libraries);

    final scripts = await scriptRefs;

    await DartUri.initialize();
    DartUri.recordAbsoluteUris(libraries.map((lib) => lib.uri).whereNotNull());
    DartUri.recordAbsoluteUris(
      scripts.map((script) => script.uri).whereNotNull(),
    );

    isolate.extensionRPCs?.addAll(await _getExtensionRpcs());
  }

  static IsolateRef _toIsolateRef(Isolate isolate) => IsolateRef(
        id: isolate.id,
        name: isolate.name,
        number: isolate.number,
        isSystemIsolate: isolate.isSystemIsolate,
      );

  static Future<AppInspector> create(
    AppConnection appConnection,
    RemoteDebugger remoteDebugger,
    AssetReader assetReader,
    Locations locations,
    String root,
    Debugger debugger,
    ExecutionContext executionContext,
  ) async {
    final id = createId();
    final time = DateTime.now().millisecondsSinceEpoch;
    final name = 'main()';
    final isolate = Isolate(
      id: id,
      number: id,
      name: name,
      startTime: time,
      runnable: true,
      pauseOnExit: false,
      pauseEvent: Event(
        kind: EventKind.kPauseStart,
        timestamp: time,
        isolate: IsolateRef(
          id: id,
          name: name,
          number: id,
          isSystemIsolate: false,
        ),
      ),
      livePorts: 0,
      libraries: [],
      breakpoints: [],
      exceptionPauseMode: debugger.pauseState,
      isSystemIsolate: false,
      isolateFlags: [],
    )..extensionRPCs = [];
    final inspector = AppInspector._(
      appConnection,
      isolate,
      remoteDebugger,
      assetReader,
      locations,
      root,
      executionContext,
    );

    debugger.updateInspector(inspector);
    await inspector.initialize();
    return inspector;
  }

  /// Returns the ID for the execution context or null if not found.
  @override
  Future<int?> get contextId async {
    try {
      return await _executionContext.id;
    } catch (e, s) {
      _logger.severe('Missing execution context ID: ', e, s);
      return null;
    }
  }

  /// Get the value of the field named [fieldName] from [receiver].
  @override
  Future<RemoteObject> loadField(RemoteObject receiver, String fieldName) {
    final load = '''
        function() {
          return ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").dart.dloadRepl(this, "$fieldName");
        }
        ''';
    return jsCallFunctionOn(receiver, load, []);
  }

  /// Call a method by name on [receiver], with arguments [positionalArgs] and
  /// [namedArgs].
  Future<RemoteObject> _invokeMethod(
    RemoteObject receiver,
    String methodName, [
    List<RemoteObject> positionalArgs = const [],
    Map namedArgs = const {},
  ]) async {
    // TODO(alanknight): Support named arguments.
    if (namedArgs.isNotEmpty) {
      throw UnsupportedError('Named arguments are not yet supported');
    }
    // We use the JS pseudo-variable 'arguments' to get the list of all arguments.
    final send = '''
        function () {
          if (!(this.__proto__)) { return 'Instance of PlainJavaScriptObject';}
          return ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").dart.dsendRepl(this, "$methodName", arguments);
        }
        ''';
    final remote = await jsCallFunctionOn(receiver, send, positionalArgs);
    return remote;
  }

  /// Calls Chrome's Runtime.callFunctionOn method.
  ///
  /// [evalExpression] should be a JS function definition that can accept
  /// [arguments].
  @override
  Future<RemoteObject> jsCallFunctionOn(
    RemoteObject receiver,
    String evalExpression,
    List<RemoteObject> arguments, {
    bool returnByValue = false,
  }) async {
    final jsArguments = arguments.map(callArgumentFor).toList();
    final response = await remoteDebugger.sendCommand(
      'Runtime.callFunctionOn',
      params: {
        'functionDeclaration': evalExpression,
        'arguments': jsArguments,
        'objectId': receiver.objectId,
        'returnByValue': returnByValue,
      },
    );
    final result =
        getResultOrHandleError(response, evalContents: evalExpression);
    return RemoteObject(result);
  }

  /// Calls Chrome's Runtime.callFunctionOn method with a global function.
  ///
  /// [evalExpression] should be a JS function definition that can accept
  /// [arguments].
  Future<RemoteObject> _jsCallFunction(
    String evalExpression,
    List<Object> arguments, {
    bool returnByValue = false,
  }) async {
    final jsArguments = arguments.map(callArgumentFor).toList();
    final response = await remoteDebugger.sendCommand(
      'Runtime.callFunctionOn',
      params: {
        'functionDeclaration': evalExpression,
        'arguments': jsArguments,
        'executionContextId': await contextId,
        'returnByValue': returnByValue,
      },
    );
    final result =
        getResultOrHandleError(response, evalContents: evalExpression);
    return RemoteObject(result);
  }

  /// Invoke the function named [selector] on the object identified by
  /// [targetId].
  ///
  /// The [targetId] can be the URL of a Dart library, in which case this means
  /// invoking a top-level function. The [arguments] are always strings that are
  /// Dart object Ids (which can also be Chrome RemoteObject objectIds that are
  /// for non-Dart JS objects.)
  @override
  Future<RemoteObject> invoke(
    String targetId,
    String selector,
    List<dynamic> arguments,
  ) async {
    final remoteArguments =
        arguments.cast<String>().map(remoteObjectFor).toList();
    // We special case the Dart library, where invokeMethod won't work because
    // it's not really a Dart object.
    if (isLibraryId(targetId)) {
      final library = await getObject(targetId) as Library;
      return await _invokeLibraryFunction(library, selector, remoteArguments);
    } else {
      return _invokeMethod(
        remoteObjectFor(targetId),
        selector,
        remoteArguments,
      );
    }
  }

  /// Invoke the function named [selector] from [library] with [arguments].
  Future<RemoteObject> _invokeLibraryFunction(
    Library library,
    String selector,
    List<RemoteObject> arguments,
  ) {
    return _evaluateInLibrary(
      library,
      'function () { return this.$selector.apply(this, arguments);}',
      arguments,
    );
  }

  /// Evaluate [expression] by calling Chrome's Runtime.evaluate.
  @override
  Future<RemoteObject> jsEvaluate(
    String expression, {
    bool returnByValue = false,
    bool awaitPromise = false,
  }) async {
    // TODO(alanknight): Support a version with arguments if needed.
    final response = await remoteDebugger.sendCommand(
      'Runtime.evaluate',
      params: {
        'expression': expression,
        'returnByValue': returnByValue,
        'awaitPromise': awaitPromise,
        'contextId': await contextId,
      },
    );
    final result = getResultOrHandleError(response, evalContents: expression);
    return RemoteObject(result);
  }

  /// Evaluate the JS function with source [jsFunction] in the context of
  /// [library] with [arguments].
  Future<RemoteObject> _evaluateInLibrary(
    Library library,
    String jsFunction,
    List<RemoteObject> arguments,
  ) async {
    final libraryUri = library.uri;
    if (libraryUri == null) {
      throwInvalidParam('invoke', 'library uri is null');
    }
    final findLibrary = '''
      (function() {
        const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk');
        const dart = sdk.dart;
        const library = dart.getLibrary('$libraryUri');
        if (!library) throw 'cannot find library for $libraryUri';
        return library;
      })();
      ''';
    final remoteLibrary = await jsEvaluate(findLibrary);
    return jsCallFunctionOn(remoteLibrary, jsFunction, arguments);
  }

  /// Call [function] with objects referred by [argumentIds] as arguments.
  @override
  Future<RemoteObject> callFunction(
    String function,
    Iterable<String> argumentIds,
  ) {
    final arguments = argumentIds.map(remoteObjectFor).toList();
    return _jsCallFunction(function, arguments);
  }

  @override
  Future<InstanceRef?> instanceRefFor(Object value) =>
      _instanceHelper.instanceRefFor(value);

  Future<Instance?> instanceFor(RemoteObject value) =>
      _instanceHelper.instanceFor(value);

  @override
  Future<LibraryRef?> libraryRefFor(String objectId) =>
      _libraryHelper.libraryRefFor(objectId);

  @override
  Future<Library?> getLibrary(String objectId) async {
    final libraryRef = await libraryRefFor(objectId);
    if (libraryRef == null) return null;
    return _libraryHelper.libraryFor(libraryRef);
  }

  @override
  Future<Obj> getObject(String objectId, {int? offset, int? count}) async {
    try {
      final library = await getLibrary(objectId);
      if (library != null) {
        return library;
      }
      final clazz = await _classHelper.forObjectId(objectId);
      if (clazz != null) {
        return clazz;
      }
      final scriptRef = _scriptRefsById[objectId];
      if (scriptRef != null) {
        return _getScript(scriptRef);
      }
      final instance = await _instanceHelper
          .instanceFor(remoteObjectFor(objectId), offset: offset, count: count);
      if (instance != null) {
        return instance;
      }
    } catch (e, s) {
      _logger.fine('getObject $objectId failed', e, s);
      rethrow;
    }
    throw UnsupportedError('Only libraries, instances, classes, and scripts '
        'are supported for getObject');
  }

  Future<Script> _getScript(ScriptRef scriptRef) async {
    final scriptId = scriptRef.id;
    final scriptUri = scriptRef.uri;
    if (scriptId == null || scriptUri == null) {
      throwInvalidParam('getObject', 'No script info for script $scriptRef');
    }
    final serverPath = DartUri(scriptUri, _root).serverPath;
    final source = await _assetReader.dartSourceContents(serverPath);
    if (source == null) {
      throwInvalidParam(
        'getObject',
        'No source for $scriptRef  with serverPath: $serverPath',
      );
    }
    final libraryId = _scriptIdToLibraryId[scriptId];
    if (libraryId == null) {
      throwInvalidParam('getObject', 'No library for script $scriptRef');
    }
    return Script(
      uri: scriptRef.uri,
      library: await libraryRefFor(libraryId),
      id: scriptId,
    )
      ..tokenPosTable = await _locations.tokenPosTableFor(serverPath)
      ..source = source;
  }

  @override
  Future<MemoryUsage> getMemoryUsage() async {
    final response = await remoteDebugger.sendCommand('Runtime.getHeapUsage');
    final result = response.result;
    if (result == null) {
      throw RPCError(
        'getMemoryUsage',
        RPCErrorKind.kInternalError.code,
        'Null result from chrome Devtools.',
      );
    }
    final jsUsage = HeapUsage(result);
    final usage = MemoryUsage.parse({
      'heapUsage': jsUsage.usedSize,
      'heapCapacity': jsUsage.totalSize,
      'externalUsage': 0,
    });
    if (usage == null) {
      throw RPCError(
        'getMemoryUsage',
        RPCErrorKind.kInternalError.code,
        'Failed to parse memory usage result.',
      );
    }
    return usage;
  }

  /// Returns the [ScriptRef] for the provided Dart server path [uri].
  @override
  Future<ScriptRef?> scriptRefFor(String uri) async {
    await _populateScriptCaches();
    return _serverPathToScriptRef[uri];
  }

  /// Returns the [ScriptRef]s in the library with [libraryId].
  @override
  Future<List<ScriptRef>> scriptRefsForLibrary(String libraryId) async {
    await _populateScriptCaches();
    return _libraryIdToScriptRefs[libraryId] ?? [];
  }

  /// Return the VM SourceReport for the given parameters.
  ///
  /// Currently this implements the 'PossibleBreakpoints' report kind.
  @override
  Future<SourceReport> getSourceReport(
    List<String> reports, {
    String? scriptId,
    int? tokenPos,
    int? endTokenPos,
    bool? forceCompile,
    bool? reportLines,
    List<String>? libraryFilters,
  }) {
    if (reports.contains(SourceReportKind.kCoverage)) {
      throwInvalidParam(
        'getSourceReport',
        'Source report kind ${SourceReportKind.kCoverage} not supported',
      );
    }

    if (reports.isEmpty) {
      throwInvalidParam(
        'getSourceReport',
        'Invalid parameter: no value for source report kind provided.',
      );
    }

    if (reports.length > 1 ||
        reports.first != SourceReportKind.kPossibleBreakpoints) {
      throwInvalidParam('getSourceReport', 'Unsupported source report kind.');
    }

    return _getPossibleBreakpoints(scriptId);
  }

  Future<SourceReport> _getPossibleBreakpoints(String? scriptId) async {
    // TODO(devoncarew): Consider adding some caching for this method.

    final scriptRef = scriptWithId(scriptId);
    if (scriptRef == null) {
      throwInvalidParam('getSourceReport', 'scriptRef not found for $scriptId');
    }
    final scriptUri = scriptRef.uri;
    if (scriptUri == null) {
      throwInvalidParam('getSourceReport', 'scriptUri not found for $scriptId');
    }

    final dartUri = DartUri(scriptUri, _root);
    final mappedLocations =
        await _locations.locationsForDart(dartUri.serverPath);
    // Unlike the Dart VM, the token positions match exactly to the possible
    // breakpoints. This is because the token positions are derived from the
    // DDC source maps which Chrome also uses.
    final tokenPositions = <int>[
      for (var location in mappedLocations) location.tokenPos,
    ];
    tokenPositions.sort();

    final range = SourceReportRange(
      scriptIndex: 0,
      startPos: tokenPositions.isEmpty ? -1 : tokenPositions.first,
      endPos: tokenPositions.isEmpty ? -1 : tokenPositions.last,
      compiled: true,
      possibleBreakpoints: tokenPositions,
    );

    final ranges = [range];
    return SourceReport(scripts: [scriptRef], ranges: ranges);
  }

  /// All the scripts in the isolate.
  @override
  Future<ScriptList> getScripts() async {
    return ScriptList(scripts: await scriptRefs);
  }

  /// Calls the Chrome Runtime.getProperties API for the object with [objectId].
  ///
  /// Note that the property names are JS names, e.g.
  /// Symbol(DartClass.actualName) and will need to be converted. For a system
  /// List or Map, [offset] and/or [count] can be provided to indicate a desired
  /// range of entries. They will be ignored if there is no [length].
  @override
  Future<List<Property>> getProperties(
    String objectId, {
    int? offset,
    int? count,
    int? length,
  }) async {
    String rangeId = objectId;
    // Ignore offset/count if there is no length:
    if (length != null) {
      if (_isEmptyRange(offset: offset, count: count, length: length)) {
        return [];
      }
      if (_isSubRange(offset: offset, count: count)) {
        final range = await _subRange(
          objectId,
          offset: offset ?? 0,
          count: count,
          length: length,
        );
        rangeId = range.objectId ?? rangeId;
      }
    }
    final jsProperties = await sendCommandAndValidateResult<List>(
      _remoteDebugger,
      method: 'Runtime.getProperties',
      resultField: 'result',
      params: {
        'objectId': rangeId,
        'ownProperties': true,
      },
    );
    return jsProperties
        .map<Property>((each) => Property(each as Map<String, dynamic>))
        .toList();
  }

  /// Calculate the number of available elements in the range.
  static int _calculateRangeCount({
    int? count,
    required int offset,
    required int length,
  }) =>
      count == null ? length - offset : math.min(count, length - offset);

  /// Find a sub-range of the entries for a Map/List when offset and/or count
  /// have been specified on a getObject request.
  ///
  /// If the object referenced by [id] is not a system List or Map then this
  /// will just return a RemoteObject for it and ignore [offset], [count] and
  /// [length]. If it is, then [length] should be the number of entries in the
  /// List/Map and [offset] and [count] should indicate the desired range.
  Future<RemoteObject> _subRange(
    String id, {
    required int offset,
    required int length,
    int? count,
  }) async {
    // TODO(#809): Sometimes we already know the type of the object, and
    // we could take advantage of that to short-circuit.
    final receiver = remoteObjectFor(id);
    final rangeCount =
        _calculateRangeCount(count: count, offset: offset, length: length);
    final args =
        [offset, rangeCount].map(dartIdFor).map(remoteObjectFor).toList();
    // If this is a List, just call sublist. If it's a Map, get the entries, but
    // avoid doing a toList on a large map using skip/take to get the section we
    // want. To make those alternatives easier in JS, pass both count and end.
    final expression = '''
      function (offset, count) {
        const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk");
        const dart = sdk.dart;
        return dart.getSubRange(this, offset, count);
      }
    ''';

    return await jsCallFunctionOn(receiver, expression, args);
  }

  static bool _isEmptyRange({
    required int length,
    int? offset,
    int? count,
  }) {
    if (count == 0) return true;
    if (offset == null) return false;
    return offset >= length;
  }

  static bool _isSubRange({
    int? offset,
    int? count,
  }) {
    if (offset == 0 && count == null) return false;
    return offset != null || count != null;
  }

  /// Returns true for objects we display for the user.
  @override
  bool isDisplayableObject(Object? object) =>
      object is Sentinel ||
      object is InstanceRef &&
          !isNativeJsObject(object) &&
          !isNativeJsError(object);

  /// Returns true for non-dart JavaScript objects.
  bool isNativeJsObject(InstanceRef instanceRef) {
    return _instanceHelper.metadataHelper
        .isNativeJsObject(instanceRef.classRef);
  }

  /// Returns true for JavaScript exceptions.
  @override
  bool isNativeJsError(InstanceRef instanceRef) {
    return _instanceHelper.metadataHelper.isNativeJsError(instanceRef.classRef);
  }

  /// Request and cache <ScriptRef>s for all the scripts in the application.
  ///
  /// This populates [_scriptRefsById], [_scriptIdToLibraryId],
  /// [_libraryIdToScriptRefs] and [_serverPathToScriptRef].
  ///
  /// It is a one-time operation, because if we do a
  /// reload the inspector will get re-created.
  ///
  /// Returns the list of scripts refs cached.
  Future<List<ScriptRef>> _populateScriptCaches() {
    return _scriptCacheMemoizer.runOnce(() async {
      final scripts = await globalToolConfiguration.loadStrategy
          .metadataProviderFor(appConnection.request.entrypointPath)
          .scripts;
      // For all the non-dart: libraries, find their parts and create scriptRefs
      // for them.
      final userLibraries =
          _userLibraryUris(isolate.libraries ?? <LibraryRef>[]);
      for (var uri in userLibraries) {
        final parts = scripts[uri];
        final scriptRefs = [
          ScriptRef(uri: uri, id: createId()),
          for (var part in parts ?? []) ScriptRef(uri: part, id: createId()),
        ];
        final libraryRef = await _libraryHelper.libraryRefFor(uri);
        final libraryId = libraryRef?.id;
        if (libraryId != null) {
          final libraryIdToScriptRefs = _libraryIdToScriptRefs.putIfAbsent(
            libraryId,
            () => <ScriptRef>[],
          );
          for (var scriptRef in scriptRefs) {
            final scriptId = scriptRef.id;
            final scriptUri = scriptRef.uri;
            if (scriptId != null && scriptUri != null) {
              _scriptRefsById[scriptId] = scriptRef;
              _scriptIdToLibraryId[scriptId] = libraryId;
              _serverPathToScriptRef[DartUri(scriptUri, _root).serverPath] =
                  scriptRef;
              libraryIdToScriptRefs.add(scriptRef);
            }
          }
        }
      }
      return _scriptRefsById.values.toList();
    });
  }

  Iterable<String> _userLibraryUris(Iterable<LibraryRef> libraries) {
    return libraries
        .map((library) => library.uri ?? '')
        .where((uri) => uri.isNotEmpty && !uri.startsWith('dart:'));
  }

  /// Look up the script by id in an isolate.
  @override
  ScriptRef? scriptWithId(String? scriptId) =>
      scriptId == null ? null : _scriptRefsById[scriptId];

  /// Runs an eval on the page to compute all existing registered extensions.
  Future<List<String>> _getExtensionRpcs() async {
    final expression =
        "${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk').developer._extensions.keys.toList();";
    final extensionRpcs = <String>[];
    final params = {
      'expression': expression,
      'returnByValue': true,
      'contextId': await contextId,
    };
    try {
      final response =
          await remoteDebugger.sendCommand('Runtime.evaluate', params: params);
      final result = getResultOrHandleError(response, evalContents: expression);
      extensionRpcs.addAll(List.from(result['value'] as List? ?? []));
    } catch (e, s) {
      _logger.severe(
        'Error calling Runtime.evaluate with params $params',
        e,
        s,
      );
    }
    return extensionRpcs;
  }

  /// Convert a JS exception description into a description containing
  /// a Dart stack trace.
  @override
  Future<String> mapExceptionStackTrace(String description) async {
    RemoteObject mapperResult;
    try {
      mapperResult = await _jsCallFunction(
        stackTraceMapperExpression,
        <Object>[description],
      );
    } catch (_) {
      return description;
    }
    final mappedStack = mapperResult.value?.toString();
    if (mappedStack == null || mappedStack.isEmpty) {
      return description;
    }
    final message = _allLinesBeforeStackTrace(description);
    return '$message$mappedStack';
  }

  String _allLinesBeforeStackTrace(String description) {
    var message = '';
    for (final match in exceptionMessageRegex.allMatches(description)) {
      final isStackTraceLine = stackTraceLineRegex.hasMatch(match[0] ?? '');
      if (isStackTraceLine) break;
      message += '${match[0]}\n';
    }
    return message;
  }
}
