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

import 'dart:math' as math;

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

final _terseRegExp = 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 = 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 = RegExp(r'    ?at ');

/// A RegExp to match Firefox's eval and Function stack traces.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack
///
/// These stack traces looks like:
///     anonymous/<@https://example.com/stuff.js line 693 > Function:3:40
///     anonymous/<@https://example.com/stuff.js line 693 > eval:3:40
final _firefoxEvalTrace = RegExp(r'@\S+ line \d+ >.* (Function|eval):\d+:\d+');

/// A RegExp to match Firefox and Safari's stack traces.
///
/// Firefox and Safari have very similar stack trace formats, so we use the same
/// logic for parsing them.
///
/// 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")@https://example.com/stuff.dart.js:560`.
///
/// 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). They can also contain
/// empty lines or lines consisting only of `[native code]`.
final _firefoxSafariTrace = RegExp(
    r'^'
    r'(' // Member description. Not present in some Safari frames.
    r'([.0-9A-Za-z_$/<]|\(.*\))*' // Member name and arguments.
    r'@'
    r')?'
    r'[^\s]*' // Frame URL.
    r':\d*' // Line or column number. Some older frames only have a line number.
    r'$',
    multiLine: true);

/// A RegExp to match this package's stack traces.
final _friendlyTrace =
    RegExp(r'^[^\s<][^\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;

  /// The original stack trace from which this trace was parsed.
  final StackTrace original;

  /// 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 = 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 ArgumentError('Argument [level] must be greater than or equal '
          'to 0.');
    }

    var trace = Trace.from(StackTrace.current);
    return LazyTrace(() {
      // JS includes a frame for the call to StackTrace.current, but the VM
      // doesn't, so we skip an extra frame in a JS context.
      return Trace(trace.frames.skip(level + (inJS ? 2 : 1)),
          original: trace.original.toString());
    });
  }

  /// 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 LazyTrace(() => 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. If it's formatted as a stack chain, this will return the equivalent
  /// of [Chain.toTrace].
  factory Trace.parse(String trace) {
    try {
      if (trace.isEmpty) return Trace(<Frame>[]);
      if (trace.contains(_v8Trace)) return Trace.parseV8(trace);
      if (trace.contains('\tat ')) return Trace.parseJSCore(trace);
      if (trace.contains(_firefoxSafariTrace) ||
          trace.contains(_firefoxEvalTrace)) {
        return Trace.parseFirefox(trace);
      }
      if (trace.contains(chainGap)) return Chain.parse(trace).toTrace();
      if (trace.contains(_friendlyTrace)) {
        return 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 Trace.parseVM(trace);
    } on FormatException catch (error) {
      throw FormatException('${error.message}\nStack trace:\n$trace');
    }
  }

  /// Parses a string representation of a Dart VM stack trace.
  Trace.parseVM(String trace) : this(_parseVM(trace), original: trace);

  static List<Frame> _parseVM(String trace) {
    // Ignore [vmChainGap]. This matches the behavior of
    // `Chain.parse().toTrace()`.
    var lines = trace
        .trim()
        .replaceAll(vmChainGap, '')
        .split('\n')
        .where((line) => line.isNotEmpty);
    return [for (var line in lines) 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) => Frame.parseV8(line)),
            original: trace);

  /// Parses a string representation of a JavaScriptCore stack trace.
  Trace.parseJSCore(String trace)
      : this(
            trace
                .split('\n')
                .where((line) => line != '\tat ')
                .map((line) => Frame.parseV8(line)),
            original: trace);

  /// 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')
                .where((line) => line.isNotEmpty && line != '[native code]')
                .map((line) => Frame.parseFirefox(line)),
            original: trace);

  /// Parses a string representation of a Safari stack trace.
  Trace.parseSafari(String trace) : this.parseFirefox(trace);

  /// Parses a string representation of a Safari 6.1+ stack trace.
  @Deprecated('Use Trace.parseSafari instead.')
  Trace.parseSafari6_1(String trace) : this.parseSafari(trace);

  /// Parses a string representation of a Safari 6.0 stack trace.
  @Deprecated('Use Trace.parseSafari instead.')
  Trace.parseSafari6_0(String trace)
      : this(
            trace
                .trim()
                .split('\n')
                .where((line) => line != '[native code]')
                .map((line) => Frame.parseFirefox(line)),
            original: trace);

  /// 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.isEmpty
                ? []
                : trace
                    .trim()
                    .split('\n')
                    // Filter out asynchronous gaps from [Chain]s.
                    .where((line) => !line.startsWith('====='))
                    .map((line) => Frame.parseFriendly(line)),
            original: trace);

  /// Returns a new [Trace] comprised of [frames].
  Trace(Iterable<Frame> frames, {String? original})
      : frames = List<Frame>.unmodifiable(frames),
        original = StackTrace.fromString(original ?? '');

  /// 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 => 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. If the outermost frame of the stack trace is a core library
  /// frame, it's removed entirely.
  ///
  /// This won't do anything with a raw JavaScript trace, since there's no way
  /// to determine which frames come from which Dart libraries. However, the
  /// [`source_map_stack_trace`][source_map_stack_trace] package can be used to
  /// convert JavaScript traces into Dart-style traces.
  ///
  /// [source_map_stack_trace]: https://pub.dev/packages/source_map_stack_trace
  ///
  /// For custom folding, see [foldFrames].
  Trace get terse => foldFrames((_) => false, terse: true);

  /// 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.
  ///
  /// If [terse] is true, this will also fold together frames from the core
  /// library or from this package, simplify core library frames, and
  /// potentially remove the outermost frame as in [Trace.terse].
  Trace foldFrames(bool Function(Frame) predicate, {bool terse = false}) {
    if (terse) {
      var oldPredicate = predicate;
      predicate = (frame) {
        if (oldPredicate(frame)) return true;

        if (frame.isCore) return true;
        if (frame.package == 'stack_trace') return true;

        // Ignore async stack frames without any line or column information.
        // These come from the VM's async/await implementation and represent
        // internal frames. They only ever show up in stack chains and are
        // always surrounded by other traces that are actually useful, so we can
        // just get rid of them.
        // TODO(nweiz): Get rid of this logic some time after issue 22009 is
        // fixed.
        if (!frame.member!.contains('<async>')) return false;
        return frame.line == null;
      };
    }

    var newFrames = <Frame>[];
    for (var frame in frames.reversed) {
      if (frame is UnparsedFrame || !predicate(frame)) {
        newFrames.add(frame);
      } else if (newFrames.isEmpty || !predicate(newFrames.last)) {
        newFrames.add(Frame(frame.uri, frame.line, frame.column, frame.member));
      }
    }

    if (terse) {
      newFrames = newFrames.map((frame) {
        if (frame is UnparsedFrame || !predicate(frame)) return frame;
        var library = frame.library.replaceAll(_terseRegExp, '');
        return Frame(Uri.parse(library), null, null, frame.member);
      }).toList();

      if (newFrames.length > 1 && predicate(newFrames.first)) {
        newFrames.removeAt(0);
      }
    }

    return Trace(newFrames.reversed, original: original.toString());
  }

  @override
  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) {
      if (frame is UnparsedFrame) return '$frame\n';
      return '${frame.location.padRight(longest)}  ${frame.member}\n';
    }).join();
  }
}
