// 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 new ArgumentError(
          "packageResolver and packageRoot may not both be passed.");
    }

    packageResolver = new SyncPackageResolver.root(packageRoot);
  }

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

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

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

  var trace = new Trace.from(stackTrace);
  return new 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 == null ? 0 : frame.column;

    // 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 new 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(new RegExp(r"/?<$"), "")
      // Get rid of arity indicators and named arguments.
      .replaceAll(new RegExp(r"\$\d+(\$[a-zA-Z_0-9]+)*$"), "")
      // Convert closures to <fn>.
      .replaceAllMapped(new 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(new RegExp(r"\.call$"), "")
      // Get rid of the top-level method prefix.
      .replaceAll(new RegExp(r"^dart\."), "")
      // Get rid of library namespaces.
      .replaceAll(new 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(new 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(new RegExp(r"([a-zA-Z0-9]+)_"),
          (match) => match[1] + ".");
}
