// Copyright (c) 2017, 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 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart';
import 'package:stack_trace/stack_trace.dart';

/// This is a fork of package:source_map_stack_trace, a tool for
/// dart2js-compiled code, reworked for DDC.

/// Convert [stackTrace], a stack trace generated by DDC-compiled
/// JavaScript, to a native-looking stack trace using [sourceMap].
///
/// [roots] are the paths (usually `http:` URI strings) that DDC applications
/// are served from.  This is used to identify sdk and package URIs.
StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
    {required List<String?> roots}) {
  if (stackTrace is Chain) {
    return Chain(stackTrace.traces.map((trace) {
      return Trace.from(mapStackTrace(sourceMap, trace, roots: roots));
    }));
  }

  var trace = Trace.from(stackTrace);
  return Trace(trace.frames.map((frame) {
    // If there's no line information, there's no way to translate this frame.
    // We could return it as-is, but these lines are usually not useful anyways.
    if (frame.line == null) return null;

    // If there's no column, try using the first column of the line.
    var column = frame.column ?? 0;

    // Subtract 1 because stack traces use 1-indexed lines and columns and
    // source maps uses 0-indexed.
    var span = sourceMap.spanFor(frame.line! - 1, column - 1,
        uri: frame.uri.toString());

    // If we can't find a source span, ignore the frame. It's probably something
    // internal that the user doesn't care about.
    if (span == null) return null;

    var sourceUrl = span.sourceUrl.toString();
    for (var root in roots) {
      if (root != null && p.url.isWithin(root, sourceUrl)) {
        var relative = p.url.relative(sourceUrl, from: root);
        if (relative.contains('dart:')) {
          sourceUrl = relative.substring(relative.indexOf('dart:'));
          break;
        }
        var packageRoot = '$root/packages';
        if (p.url.isWithin(packageRoot, sourceUrl)) {
          sourceUrl = 'package:${p.url.relative(sourceUrl, from: packageRoot)}';
          break;
        }
      }
    }

    if (!sourceUrl.startsWith('dart:') &&
        !sourceUrl.startsWith('package:') &&
        sourceUrl.contains('dart_sdk')) {
      // This compresses the long dart_sdk URLs if SDK source maps are missing.
      // It's no longer linkable, but neither are the properly mapped ones
      // above.
      sourceUrl = 'dart:sdk_internal';
    }

    return Frame(Uri.parse(sourceUrl), span.start.line + 1,
        span.start.column + 1, _prettifyMember(frame.member!));
  }).nonNulls);
}

final escapedPipe = '\$124';
final escapedPound = '\$35';

/// Reformats a JS member name to make it look more Dart-like.
///
/// Logic copied from build/build_web_compilers/web/stack_trace_mapper.dart.
/// TODO(https://github.com/dart-lang/sdk/issues/38869): Remove this logic when
/// DDC stack trace deobfuscation is overhauled.
String _prettifyMember(String member) {
  var last = member.lastIndexOf('.');
  if (last < 0) return member;
  var suffix = member.substring(last + 1);
  member = suffix == 'fn' ? member : suffix;
  // We avoid unescaping the entire member here due to DDC's deduping mechanism
  // introducing trailing $N.
  member = member.replaceAll(escapedPipe, '|');
  return member.contains('|') ? _prettifyExtension(member) : member;
}

/// Reformats a JS member name as an extension method invocation.
String _prettifyExtension(String member) {
  var isSetter = false;
  var pipeIndex = member.indexOf('|');
  var spaceIndex = member.indexOf(' ');
  var poundIndex = member.indexOf('escapedPound');
  if (spaceIndex >= 0) {
    // Here member is a static field or static getter/setter.
    isSetter = member.substring(0, spaceIndex) == 'set';
    member = member.substring(spaceIndex + 1, member.length);
  } else if (poundIndex >= 0) {
    // Here member is a tearoff or local property getter/setter.
    isSetter = member.substring(pipeIndex + 1, poundIndex) == 'set';
    member = member.replaceRange(pipeIndex + 1, poundIndex + 3, '');
  } else {
    var body = member.substring(pipeIndex + 1, member.length);
    if (body.startsWith('unary') || body.startsWith('\$')) {
      // Here member's an operator, so it's safe to unescape everything lazily.
      member = _unescape(member);
    }
  }
  member = member.replaceAll('|', '.');
  return isSetter ? '$member=' : member;
}

/// Unescapes a DDC-escaped JS identifier name.
///
/// Identifier names that contain illegal JS characters are escaped by DDC to a
/// decimal representation of the symbol's UTF-16 value.
/// Warning: this greedily escapes characters, so it can be unsafe in the event
/// that an escaped sequence precedes a number literal in the JS name.
String _unescape(String name) {
  return name.replaceAllMapped(
      RegExp(r'\$[0-9]+'),
      (m) =>
          String.fromCharCode(int.parse(name.substring(m.start + 1, m.end))));
}
