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

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

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

    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] + ".");
}
