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

import 'package:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart';
import 'package:stack_trace/stack_trace.dart';

/// Convert [stackTrace], a stack trace generated by dart2js-compiled
/// JavaScript, to a native-looking stack trace using [sourceMap].
///
/// [minified] indicates whether or not the dart2js code was minified. If it
/// hasn't, this tries to clean up the stack frame member names.
///
/// If [packageResolver] is passed, it's used to reconstruct `package:` URIs for
/// stack frames that come from packages.
///
/// [sdkRoot] is the URI (usually a `file:` URI) for the SDK containing dart2js.
/// It can be a [String] or a [Uri]. If it's passed, stack frames from the SDK
/// will have `dart:` URLs.
///
/// `packageRoot` is deprecated and shouldn't be used in new code. This throws
/// an [ArgumentError] if `packageRoot` and [packageResolver] are both passed.
StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
    {bool minified = false,
    SyncPackageResolver packageResolver,
    sdkRoot,
    @Deprecated('Use the packageResolver parameter instead.') packageRoot}) {
  if (packageRoot != null) {
    if (packageResolver != null) {
      throw ArgumentError(
          'packageResolver and packageRoot may not both be passed.');
    }

    packageResolver = SyncPackageResolver.root(packageRoot);
  }

  if (stackTrace is Chain) {
    return Chain(stackTrace.traces.map((trace) {
      return Trace.from(mapStackTrace(sourceMap, trace,
          minified: minified,
          packageResolver: packageResolver,
          sdkRoot: sdkRoot));
    }));
  }

  if (sdkRoot != null && sdkRoot is! String && sdkRoot is! Uri) {
    throw ArgumentError('sdkRoot must be a String or a Uri, was "$sdkRoot".');
  }

  var sdkLib = sdkRoot == null ? null : '$sdkRoot/lib';

  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();
    if (sdkRoot != null && p.url.isWithin(sdkLib, sourceUrl)) {
      sourceUrl = 'dart:' + p.url.relative(sourceUrl, from: sdkLib);
    } else if (packageResolver != null) {
      if (packageResolver.packageRoot != null &&
          p.url.isWithin(packageResolver.packageRoot.toString(), sourceUrl)) {
        sourceUrl = 'package:' +
            p.url.relative(sourceUrl,
                from: packageResolver.packageRoot.toString());
      } else if (packageResolver.packageConfigMap != null) {
        for (var package in packageResolver.packageConfigMap.keys) {
          var packageUrl = packageResolver.packageConfigMap[package].toString();
          if (!p.url.isWithin(packageUrl, sourceUrl)) continue;

          sourceUrl =
              'package:$package/' + p.url.relative(sourceUrl, from: packageUrl);
          break;
        }
      }
    }

    return Frame(
        Uri.parse(sourceUrl),
        span.start.line + 1,
        span.start.column + 1,
        // If the dart2js output is minified, there's no use trying to prettify
        // its member names. Use the span's identifier if available, otherwise
        // use the minified member name.
        minified
            ? (span.isIdentifier ? span.text : frame.member)
            : _prettifyMember(frame.member));
  }).where((frame) => frame != null));
}

/// Reformats a JS member name to make it look more Dart-like.
String _prettifyMember(String member) {
  return member
      // Get rid of the noise that Firefox sometimes adds.
      .replaceAll(RegExp(r'/?<$'), '')
      // Get rid of arity indicators and named arguments.
      .replaceAll(RegExp(r'\$\d+(\$[a-zA-Z_0-9]+)*$'), '')
      // Convert closures to <fn>.
      .replaceAllMapped(
          RegExp(r'(_+)closure\d*\.call$'),
          // The number of underscores before "closure" indicates how nested it
          // is.
          (match) => '.<fn>' * match[1].length)
      // Get rid of explicitly-generated calls.
      .replaceAll(RegExp(r'\.call$'), '')
      // Get rid of the top-level method prefix.
      .replaceAll(RegExp(r'^dart\.'), '')
      // Get rid of library namespaces.
      .replaceAll(RegExp(r'[a-zA-Z_0-9]+\$'), '')
      // Get rid of the static method prefix. The class name also exists in the
      // invocation, so we're not getting rid of any information.
      .replaceAll(RegExp(r'^[a-zA-Z_0-9]+.(static|dart).'), '')
      // Convert underscores after identifiers to dots. This runs the risk of
      // incorrectly converting members that contain underscores, but those are
      // contrary to the style guide anyway.
      .replaceAllMapped(RegExp(r'([a-zA-Z0-9]+)_'), (match) => match[1] + '.');
}
