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

library source_map_stack_trace;

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.
///
/// [packageRoot] is the URI (usually a `file:` URI) for the package root that
/// was used by dart2js. It can be a [String] or a [Uri]. If it's passed, stack
/// frames from packages will use `package:` URLs.
///
/// [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.
StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
    {bool minified: false, packageRoot, sdkRoot}) {
  if (stackTrace is Chain) {
    return new Chain(stackTrace.traces.map((trace) {
      return new Trace.from(mapStackTrace(sourceMap, trace,
          minified: minified, packageRoot: packageRoot, sdkRoot: sdkRoot));
    }));
  }

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

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

  packageRoot = packageRoot == null ? null : packageRoot.toString();
  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;
    var span = sourceMap.spanFor(frame.line, column);

    // 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 (packageRoot != null && p.url.isWithin(packageRoot, sourceUrl)) {
      sourceUrl = "package:" +
          p.url.relative(sourceUrl, from: packageRoot);
    } else if (sdkRoot != null && p.url.isWithin(sdkLib, sourceUrl)) {
      sourceUrl = "dart:" + p.url.relative(sourceUrl, from: sdkLib);
    }

    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.
      .replaceAll(new RegExp(r"\$\d+$"), "")
      // 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."), "")
      // 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] + ".");
}
