// 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 Trace = void Function(String message,
    {bool Function(String stackTrace) condition, 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 TraceAndReport = void Function(
    DiagnosticReporter reporter, Spannable node, String message,
    {bool Function(String stackTrace) condition, 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 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 = RegExp(r'#\d+\s*');
    int index = -1;
    int maxFileLength = 0;
    int maxLineNoLength = 0;
    int maxColumnNoLength = 0;

    String stackTrace = '$s';
    List<StackTraceLine> lines = [];
    // 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(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(StackTraceLine(index, file, lineNo, columnNo, method));
      } catch (e) {
        throw 'Error prettifying "$line": $e';
      }
    }
    return StackTraceLines.fromLines(
        lines, maxFileLength, maxLineNoLength, maxColumnNoLength);
  }

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

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

  String prettify({bool showColumnNo = false, bool showDots = true}) {
    StringBuffer sb = 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 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 = 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();
}
