// Copyright (c) 2013, 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 trace;

import 'dart:collection';
import 'dart:math' as math;

import 'chain.dart';
import 'frame.dart';
import 'lazy_trace.dart';
import 'utils.dart';
import 'vm_trace.dart';

final _terseRegExp = new RegExp(r"(-patch)?(/.*)?$");

/// A RegExp to match V8's stack traces.
///
/// V8's traces start with a line that's either just "Error" or else is a
/// description of the exception that occurred. That description can be multiple
/// lines, so we just look for any line other than the first that begins with
/// three or four spaces and "at".
final _v8Trace = new RegExp(r"\n    ?at ");

/// A RegExp to match indidual lines of V8's stack traces.
///
/// This is intended to filter out the leading exception details of the trace
/// though it is possible for the message to match this as well.
final _v8TraceLine = new RegExp(r"    ?at ");

/// A RegExp to match Safari's stack traces.
///
/// Prior to version 6, Safari's stack traces were uncapturable. In v6 they were
/// almost identical to Firefox traces, and so are handled by the Firefox code.
/// In v6.1+, they have their own format that's similar to Firefox but distinct
/// enough to warrant handling separately.
///
/// Most notably, Safari traces occasionally don't include the initial method
/// name followed by "@", and they always have both the line and column number
/// (or just a trailing colon if no column number is available).
final _safariTrace = new RegExp(r"^([0-9A-Za-z_$]*@)?.*:\d*:\d*$",
    multiLine: true);

/// A RegExp to match Firefox's stack traces.
///
/// Firefox's trace frames start with the name of the function in which the
/// error occurred, possibly including its parameters inside `()`. For example,
/// `.VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560`.
final _firefoxTrace = new RegExp(r"^([.0-9A-Za-z_$/<]|\(.*\))*@");

/// A RegExp to match this package's stack traces.
final _friendlyTrace = new RegExp(r"^[^\s]+( \d+(:\d+)?)?[ \t]+[^\s]+$",
    multiLine: true);

/// A stack trace, comprised of a list of stack frames.
class Trace implements StackTrace {
  /// The stack frames that comprise this stack trace.
  final List<Frame> frames;

  /// Returns a human-readable representation of [stackTrace]. If [terse] is
  /// set, this folds together multiple stack frames from the Dart core
  /// libraries, so that only the core library method directly called from user
  /// code is visible (see [Trace.terse]).
  static String format(StackTrace stackTrace, {bool terse: true}) {
    var trace = new Trace.from(stackTrace);
    if (terse) trace = trace.terse;
    return trace.toString();
  }

  /// Returns the current stack trace.
  ///
  /// By default, the first frame of this trace will be the line where
  /// [Trace.current] is called. If [level] is passed, the trace will start that
  /// many frames up instead.
  factory Trace.current([int level=0]) {
    if (level < 0) {
      throw new ArgumentError("Argument [level] must be greater than or equal "
          "to 0.");
    }

    try {
      throw '';
    } catch (_, nativeTrace) {
      var trace = new Trace.from(nativeTrace);
      return new LazyTrace(() => new Trace(trace.frames.skip(level + 1)));
    }
  }

  /// Returns a new stack trace containing the same data as [trace].
  ///
  /// If [trace] is a native [StackTrace], its data will be parsed out; if it's
  /// a [Trace], it will be returned as-is.
  factory Trace.from(StackTrace trace) {
    if (trace is Trace) return trace;
    if (trace is Chain) return trace.toTrace();
    return new LazyTrace(() => new Trace.parse(trace.toString()));
  }

  /// Parses a string representation of a stack trace.
  ///
  /// [trace] should be formatted in the same way as a Dart VM or browser stack
  /// trace.
  factory Trace.parse(String trace) {
    try {
      if (trace.isEmpty) return new Trace(<Frame>[]);
      if (trace.contains(_v8Trace)) return new Trace.parseV8(trace);
      // Safari 6.1+ traces could be misinterpreted as Firefox traces, so we
      // check for them first.
      if (trace.contains(_safariTrace)) return new Trace.parseSafari6_1(trace);
      // Safari 6.0 traces are a superset of Firefox traces, so we parse those
      // two together.
      if (trace.contains(_firefoxTrace)) return new Trace.parseSafari6_0(trace);
      if (trace.contains(_friendlyTrace)) {
        return new Trace.parseFriendly(trace);
      }

      // Default to parsing the stack trace as a VM trace. This is also hit on
      // IE and Safari, where the stack trace is just an empty string (issue
      // 11257).
      return new Trace.parseVM(trace);
    } on FormatException catch (error) {
      throw new FormatException('${error.message}\nStack trace:\n$trace');
    }
  }

  /// Parses a string representation of a Dart VM stack trace.
  Trace.parseVM(String trace)
      : this(trace.trim().split("\n").map((line) => new Frame.parseVM(line)));

  /// Parses a string representation of a Chrome/V8 stack trace.
  Trace.parseV8(String trace)
      : this(trace.split("\n").skip(1)
          // It's possible that an Exception's description contains a line that
          // looks like a V8 trace line, which will screw this up.
          // Unfortunately, that's impossible to detect.
          .skipWhile((line) => !line.startsWith(_v8TraceLine))
          .map((line) => new Frame.parseV8(line)));

  /// Parses a string representation of an Internet Explorer stack trace.
  ///
  /// IE10+ traces look just like V8 traces. Prior to IE10, stack traces can't
  /// be retrieved.
  Trace.parseIE(String trace)
      : this.parseV8(trace);

  /// Parses a string representation of a Firefox stack trace.
  Trace.parseFirefox(String trace)
      : this(trace.trim().split("\n")
          .map((line) => new Frame.parseFirefox(line)));

  /// Parses a string representation of a Safari stack trace.
  ///
  /// This will automatically decide between [parseSafari6_0] and
  /// [parseSafari6_1] based on the contents of [trace].
  factory Trace.parseSafari(String trace) {
    if (trace.contains(_safariTrace)) return new Trace.parseSafari6_1(trace);
    return new Trace.parseSafari6_0(trace);
  }

  /// Parses a string representation of a Safari 6.1+ stack trace.
  Trace.parseSafari6_1(String trace)
      : this(trace.trim().split("\n")
          .map((line) => new Frame.parseSafari6_1(line)));

  /// Parses a string representation of a Safari 6.0 stack trace.
  ///
  /// Safari 6.0 stack traces look just like Firefox traces, except that they
  /// sometimes (e.g. in isolates) have a "[native code]" frame. We just ignore
  /// this frame to make the stack format more consistent between browsers.
  /// Prior to Safari 6.0, stack traces can't be retrieved.
  Trace.parseSafari6_0(String trace)
      : this(trace.trim().split("\n")
          .where((line) => line != '[native code]')
          .map((line) => new Frame.parseFirefox(line)));

  /// Parses this package's string representation of a stack trace.
  ///
  /// This also parses string representations of [Chain]s. They parse to the
  /// same trace that [Chain.toTrace] would return.
  Trace.parseFriendly(String trace)
      : this(trace.trim().split("\n")
          // Filter out asynchronous gaps from [Chain]s.
          .where((line) => !line.startsWith('====='))
          .map((line) => new Frame.parseFriendly(line)));

  /// Returns a new [Trace] comprised of [frames].
  Trace(Iterable<Frame> frames)
      : frames = new UnmodifiableListView<Frame>(frames.toList());

  /// Returns a VM-style [StackTrace] object.
  ///
  /// The return value's [toString] method will always return a string
  /// representation in the Dart VM's stack trace format, regardless of what
  /// platform is being used.
  StackTrace get vmTrace => new VMTrace(frames);

  /// Returns a terser version of [this].
  ///
  /// This is accomplished by folding together multiple stack frames from the
  /// core library or from this package, as in [foldFrames]. Remaining core
  /// library frames have their libraries, "-patch" suffixes, and line numbers
  /// removed.
  Trace get terse {
    return new Trace(foldFrames((frame) {
      return frame.isCore || frame.package == 'stack_trace';
    }).frames.map((frame) {
      if (!frame.isCore) return frame;
      var library = frame.library.replaceAll(_terseRegExp, '');
      return new Frame(Uri.parse(library), null, null, frame.member);
    }));
  }

  /// Returns a new [Trace] based on [this] where multiple stack frames matching
  /// [predicate] are folded together. This means that whenever there are
  /// multiple frames in a row that match [predicate], only the last one is
  /// kept.
  ///
  /// This is useful for limiting the amount of library code that appears in a
  /// stack trace by only showing user code and code that's called by user code.
  Trace foldFrames(bool predicate(frame)) {
    var newFrames = <Frame>[];
    for (var frame in frames.reversed) {
      if (!predicate(frame)) {
        newFrames.add(frame);
      } else if (newFrames.isEmpty || !predicate(newFrames.last)) {
        newFrames.add(new Frame(
            frame.uri, frame.line, frame.column, frame.member));
      }
    }

    return new Trace(newFrames.reversed);
  }

  /// Returns a human-readable string representation of [this].
  String toString() {
    // Figure out the longest path so we know how much to pad.
    var longest = frames.map((frame) => frame.location.length)
        .fold(0, math.max);

    // Print out the stack trace nicely formatted.
    return frames.map((frame) {
      return '${padRight(frame.location, longest)}  ${frame.member}\n';
    }).join();
  }
}
