// 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 'frame.dart';
import 'lazy_trace.dart';

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

/// 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;
    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 native stack traces.
  Trace.parse(String trace)
      : this(trace.trim().split("\n").map((line) => new Frame.parse(line)));

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

  // TODO(nweiz): Keep track of which [Frame]s are part of the partial stack
  // trace and only print them.
  /// Returns a string representation of this stack trace.
  ///
  /// This is identical to [toString]. It will not be formatted in the manner of
  /// native stack traces.
  String get stackTrace => toString();

  /// Returns a string representation of this stack trace.
  ///
  /// This is identical to [toString]. It will not be formatted in the manner of
  /// native stack traces.
  String get fullStackTrace => toString();

  /// Returns a terser version of [this].
  ///
  /// This is accomplished by folding together multiple stack frames from the
  /// core library, as in [foldFrames]. Remaining core library frames have their
  /// libraries, "-patch" suffixes, and line numbers removed.
  Trace get terse {
    return new Trace(foldFrames((frame) => frame.isCore).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() {
    if (frames.length == '') return '';

    // Figure out the longest path so we know how much to pad.
    var longest = frames.map((frame) => frame.location.length).reduce(math.max);

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

/// Returns [string] with enough spaces added to the end to make it [length]
/// characters long.
String _padRight(String string, int length) {
  if (string.length >= length) return string;

  var result = new StringBuffer();
  result.write(string);
  for (var i = 0; i < length - string.length; i++) {
    result.write(' ');
  }

  return result.toString();
}
