// Copyright (c) 2014, 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 '../common.dart';
import '../util/util.dart';

/// Function signature for [trace].
typedef void Trace(String message,
    {bool condition(String stackTrace), int limit, bool throwOnPrint});

/// Helper method for printing stack traces for debugging.
///
/// [message] is printed as the header of the stack trace.
///
/// If [condition] is provided, the stack trace is only printed if [condition]
/// returns [:true:] on the stack trace text. This can be used to filter the
/// printed stack traces based on their content. For instance only print stack
/// traces that contain specific paths.
///
/// If [limit] is provided, the stack trace is limited to [limit] entries.
///
/// If [throwOnPrint] is `true`, [message] will be thrown after the stack trace
/// has been printed. Together with [condition] this can be used to discover
/// unknown call-sites in tests by filtering known call-sites and throwning
/// otherwise.
Trace get trace {
  enableDebugMode();
  return _trace;
}

void _trace(String message,
    {bool condition(String stackTrace), int limit, bool throwOnPrint: false}) {
  try {
    throw '';
  } catch (e, s) {
    String stackTrace;
    try {
      stackTrace = prettifyStackTrace(s,
          rangeStart: 1, rangeEnd: limit, filePrefix: stackTraceFilePrefix);
    } catch (e) {
      print(e);
      stackTrace = '$s';
    }
    if (condition != null) {
      if (!condition(stackTrace)) return;
    }
    print('$message\n$stackTrace');
    if (throwOnPrint) throw message;
  }
}

/// Creates a function to use as an `condition` argument in [trace] that filters
/// stack traces that contains any of the [exceptions].
traceExceptions(List<String> exceptions) {
  return (String stackTrace) => !exceptions.any(stackTrace.contains);
}

/// Function signature of [traceAndReport].
typedef void TraceAndReport(
    DiagnosticReporter reporter, Spannable node, String message,
    {bool condition(String stackTrace), int limit, bool throwOnPrint});

/// Calls [reportHere] and [trace] with the same message.
TraceAndReport get traceAndReport {
  enableDebugMode();
  return _traceAndReport;
}

/// Calls [reportHere] and [trace] with the same message.
TraceAndReport get reportAndTrace => traceAndReport;

/// Implementation of [traceAndReport].
void _traceAndReport(
    DiagnosticReporter reporter, Spannable node, String message,
    {bool condition(String stackTrace), int limit, bool throwOnPrint: false}) {
  trace(message, limit: limit, throwOnPrint: throwOnPrint,
      condition: (String stackTrace) {
    bool result = condition != null ? condition(stackTrace) : true;
    if (result) {
      reportHere(reporter, node, message);
    }
    return result;
  });
}

/// Returns the [StackTraceLines] for the current call stack.
///
/// Use [offset] to discard the first [offset] calls of the call stack. Defaults
/// to `1`, that is, discard the call to [stackTrace] itself. Use [limit] to
/// limit the length of the stack trace lines.
StackTraceLines stackTrace({int offset: 1, int limit: null}) {
  int rangeStart = offset;
  int rangeEnd = limit == null ? null : rangeStart + limit;
  try {
    throw '';
  } catch (_, stackTrace) {
    return new StackTraceLines.fromTrace(stackTrace,
        rangeStart: offset,
        rangeEnd: rangeEnd,
        filePrefix: stackTraceFilePrefix);
  }
}

/// A stack trace as a sequence of [StackTraceLine]s.
class StackTraceLines {
  final List<StackTraceLine> lines;
  final int maxFileLength;
  final int maxLineNoLength;
  final int maxColumnNoLength;

  factory StackTraceLines.fromTrace(StackTrace s,
      {int rangeStart, int rangeEnd, String filePrefix, String lambda: r'?'}) {
    final RegExp indexPattern = new RegExp(r'#\d+\s*');
    int index = -1;
    int maxFileLength = 0;
    int maxLineNoLength = 0;
    int maxColumnNoLength = 0;

    String stackTrace = '$s';
    List<StackTraceLine> lines = <StackTraceLine>[];
    // Parse each line in the stack trace. The supported line formats from the
    // Dart VM are:
    //    #n     <method-name> (<uri>:<line-no>:<column-no>)
    //    #n     <method-name> (<uri>:<line-no>)
    //    #n     <method-name> (<uri>)
    // in which '<anonymous closure>' is the name used for an (unnamed) function
    // expression. The last case is used for async bodies.
    for (String line in stackTrace.split('\n')) {
      try {
        index++;
        if (rangeStart != null && index < rangeStart) continue;
        if (rangeEnd != null && index > rangeEnd) break;
        if (line.isEmpty) continue;

        // Strip index.
        line = line.replaceFirst(indexPattern, '');
        if (line == '<asynchronous suspension>') {
          lines.add(new StackTraceLine(index, '', '', '', line));
          continue;
        }

        int leftParenPos = line.indexOf('(');
        int rightParenPos = line.indexOf(')', leftParenPos);
        int lastColon = line.lastIndexOf(':', rightParenPos);
        int nextToLastColon = line.lastIndexOf(':', lastColon - 1);

        String lineNo;
        String columnNo;
        if (nextToLastColon != -1) {
          lineNo = line.substring(nextToLastColon + 1, lastColon);
          columnNo = line.substring(lastColon + 1, rightParenPos);
          try {
            int.parse(columnNo);
            try {
              int.parse(lineNo);
            } on FormatException {
              // Only line number.
              lineNo = columnNo;
              columnNo = '';
              nextToLastColon = lastColon;
            }
          } on FormatException {
            // No column number nor line number.
            lineNo = '';
            columnNo = '';
            nextToLastColon = rightParenPos;
          }
        } else {
          lineNo = line.substring(lastColon + 1, rightParenPos);
          columnNo = '';
          try {
            int.parse(lineNo);
            nextToLastColon = lastColon;
          } on FormatException {
            // No column number nor line number.
            lineNo = columnNo;
            columnNo = '';
            nextToLastColon = rightParenPos;
          }
        }

        if (lineNo.length > maxLineNoLength) {
          maxLineNoLength = lineNo.length;
        }
        if (columnNo.length > maxColumnNoLength) {
          maxColumnNoLength = columnNo.length;
        }

        String file = line.substring(leftParenPos + 1, nextToLastColon);
        if (filePrefix != null && file.startsWith(filePrefix)) {
          file = file.substring(filePrefix.length);
        }
        if (file.length > maxFileLength) {
          maxFileLength = file.length;
        }
        String method = line.substring(0, leftParenPos - 1);
        if (lambda != null) {
          method = method.replaceAll('<anonymous closure>', lambda);
        }
        lines.add(new StackTraceLine(index, file, lineNo, columnNo, method));
      } catch (e) {
        throw 'Error prettifying "$line": $e';
      }
    }
    return new StackTraceLines.fromLines(
        lines, maxFileLength, maxLineNoLength, maxColumnNoLength);
  }

  StackTraceLines.fromLines(this.lines, this.maxFileLength,
      this.maxLineNoLength, this.maxColumnNoLength);

  StackTraceLines subtrace(int offset) {
    return new StackTraceLines.fromLines(lines.sublist(offset), maxFileLength,
        maxLineNoLength, maxColumnNoLength);
  }

  String prettify({bool showColumnNo: false, bool showDots: true}) {
    StringBuffer sb = new StringBuffer();
    bool dots = true;
    for (StackTraceLine line in lines) {
      sb.write('  ');
      line.printOn(sb,
          fileLength: maxFileLength,
          padding: showDots && dots ? ' .' : ' ',
          lineNoLength: maxLineNoLength,
          showColumnNo: showColumnNo,
          columnNoLength: maxColumnNoLength);

      dots = !dots;
    }
    return sb.toString();
  }

  @override
  String toString() {
    return prettify();
  }
}

/// A parsed line from a stack trace.
class StackTraceLine {
  final int index;
  final String file;
  final String lineNo;
  final String columnNo;
  final String method;

  StackTraceLine(
      this.index, this.file, this.lineNo, this.columnNo, this.method);

  void printOn(StringBuffer sb,
      {String padding: ' ',
      int fileLength,
      int lineNoLength,
      int columnNoLength,
      bool showColumnNo: false}) {
    String fileText = '${file} ';
    if (fileLength != null) {
      fileText = pad(fileText, fileLength, dots: padding);
    }
    String lineNoText = lineNo;
    if (lineNoLength != null) {
      lineNoText = pad(lineNoText, lineNoLength, padLeft: true);
    }
    String columnNoText = showColumnNo ? '' : columnNo;
    if (columnNoLength != null) {
      columnNoText = ':${pad(columnNoText, columnNoLength)}';
    }
    sb.write('$fileText $lineNoText$columnNoText $method\n');
  }

  @override
  int get hashCode {
    return 13 * index +
        17 * file.hashCode +
        19 * lineNo.hashCode +
        23 * columnNo.hashCode +
        29 * method.hashCode;
  }

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! StackTraceLine) return false;
    return index == other.index &&
        file == other.file &&
        lineNo == other.lineNo &&
        columnNo == other.columnNo &&
        method == other.method;
  }

  @override
  String toString() => "$method @ $file [$lineNo:$columnNo]";
}

// TODO(johnniwinther): Use this format for --throw-on-error.
/// Converts the normal VM stack trace into a more compact and readable format.
///
/// The output format is `<file> . . . <lineNo>:<columnNo> <method>` where
/// `<file>` is file name, `<lineNo>` is the line number, `<columnNo>` is the
/// column number, and `<method>` is the method name.
///
/// If [rangeStart] and/or [rangeEnd] are provided, only the lines within the
/// range are included.
/// If [showColumnNo] is `false`, the `:<columnNo>` part is omitted.
/// If [showDots] is `true`, the space between `<file>` and `<lineNo>` is padded
/// with dots on every other line.
/// If [filePrefix] is provided, then for  every file name thats starts with
/// [filePrefix] only the remainder is printed.
/// If [lambda] is non-null, anonymous closures are printed as [lambda].
String prettifyStackTrace(StackTrace stackTrace,
    {int rangeStart,
    int rangeEnd,
    bool showColumnNo: false,
    bool showDots: true,
    String filePrefix,
    String lambda: r'?'}) {
  return new StackTraceLines.fromTrace(stackTrace,
          rangeStart: rangeStart,
          rangeEnd: rangeEnd,
          filePrefix: filePrefix,
          lambda: lambda)
      .prettify(showColumnNo: showColumnNo, showDots: showDots);
}

/// Pads (or truncates) [text] to the [intendedLength].
///
/// If [padLeft] is [:true:] the text is padding inserted to the left of [text].
/// A repetition of the [dots] text is used for padding.
String pad(String text, int intendedLength,
    {bool padLeft: false, String dots: ' '}) {
  if (text.length == intendedLength) return text;
  if (text.length > intendedLength) return text.substring(0, intendedLength);
  if (dots == null || dots.isEmpty) dots = ' ';
  int dotsLength = dots.length;
  StringBuffer sb = new StringBuffer();
  if (!padLeft) {
    sb.write(text);
  }
  for (int index = text.length; index < intendedLength; index++) {
    int dotsIndex = index % dotsLength;
    sb.write(dots.substring(dotsIndex, dotsIndex + 1));
  }
  if (padLeft) {
    sb.write(text);
  }
  return sb.toString();
}
