// 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>))
        .where(_isVisibleProperty)
        .toList();
  }

  bool _isVisibleProperty(Property property) {
    // Filter out any RTI objects from the new DDC type system. See:
    // https://github.com/dart-lang/webdev/issues/2316
    final isRtiObject =
        property.value?.className?.startsWith('dart_rti.Rti') ?? false;
    return !isRtiObject;
  }

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