// Copyright (c) 2019, 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:async";
import "dart:math";

import "dwarf.dart";

String _stackTracePiece(CallInfo call, int depth) => "#${depth}\t${call}";

// A pattern matching the last line of the non-symbolic stack trace header.
//
// Currently, this happens to include the only pieces of information from the
// stack trace header we need: the absolute addresses during program
// execution of the start of the isolate and VM instructions.
final _headerEndRE =
    RegExp(r'isolate_instructions: ([\da-f]+) vm_instructions: ([\da-f]+)$');

// Parses instructions section information into a new [StackTraceHeader].
//
// Returns a new [StackTraceHeader] if [line] contains the needed header
// information, otherwise returns `null`.
StackTraceHeader _parseInstructionsLine(String line) {
  final match = _headerEndRE.firstMatch(line);
  if (match == null) return null;
  final isolateAddr = int.parse(match[1], radix: 16);
  final vmAddr = int.parse(match[2], radix: 16);
  return StackTraceHeader(isolateAddr, vmAddr);
}

/// Header information for a non-symbolic Dart stack trace.
class StackTraceHeader {
  final int _isolateStart;
  final int _vmStart;

  StackTraceHeader(this._isolateStart, this._vmStart);

  /// The [PCOffset] for the given absolute program counter address.
  PCOffset offsetOf(int address) {
    final isolateOffset = address - _isolateStart;
    int vmOffset = address - _vmStart;
    if (vmOffset > 0 && vmOffset == min(vmOffset, isolateOffset)) {
      return PCOffset(vmOffset, InstructionsSection.vm);
    } else {
      return PCOffset(isolateOffset, InstructionsSection.isolate);
    }
  }
}

/// A Dart DWARF stack trace contains up to four pieces of information:
///   - The zero-based frame index from the top of the stack.
///   - The absolute address of the program counter.
///   - The virtual address of the program counter, if the snapshot was
///     loaded as a dynamic library, otherwise not present.
///   - The path to the snapshot, if it was loaded as a dynamic library,
///     otherwise the string "<unknown>".
final _traceLineRE =
    RegExp(r'    #(\d{2}) abs ([\da-f]+)(?: virt ([\da-f]+))? (.*)$');

PCOffset _retrievePCOffset(StackTraceHeader header, Match match) {
  if (header == null || match == null) return null;
  final address = int.tryParse(match[2], radix: 16);
  return header.offsetOf(address);
}

/// The [PCOffset]s for frames of the non-symbolic stack traces in [lines].
Iterable<PCOffset> collectPCOffsets(Iterable<String> lines) sync* {
  StackTraceHeader header;
  for (var line in lines) {
    final parsedHeader = _parseInstructionsLine(line);
    if (parsedHeader != null) {
      header = parsedHeader;
      continue;
    }
    final match = _traceLineRE.firstMatch(line);
    final offset = _retrievePCOffset(header, match);
    if (offset != null) yield offset;
  }
}

/// A [StreamTransformer] that scans lines for non-symbolic stack traces.
///
/// A [NativeStackTraceDecoder] scans a stream of lines for non-symbolic
/// stack traces containing only program counter address information. Such
/// stack traces are generated by the VM when executing a snapshot compiled
/// with `--dwarf-stack-traces`.
///
/// The transformer assumes that there may be text preceding the stack frames
/// on individual lines, like in log files, but that there is no trailing text.
/// For each stack frame found, the transformer attempts to locate a function
/// name, file name and line number using the provided DWARF information.
///
/// If no information is found, or the line is not a stack frame, then the line
/// will be unchanged in the output stream.
///
/// If the located information corresponds to Dart internals and
/// [includeInternalFrames] is false, then the output stream contains no
/// entries for the line.
///
/// Otherwise, the output stream contains one or more lines with symbolic stack
/// frames for the given non-symbolic stack frame line. Multiple symbolic stack
/// frame lines are generated when the PC address corresponds to inlined code.
/// In the output stream, each symbolic stack frame is prefixed by the non-stack
/// frame portion of the original line.
class DwarfStackTraceDecoder extends StreamTransformerBase<String, String> {
  final Dwarf _dwarf;
  final bool _includeInternalFrames;

  DwarfStackTraceDecoder(this._dwarf, {bool includeInternalFrames = false})
      : _includeInternalFrames = includeInternalFrames;

  Stream<String> bind(Stream<String> stream) async* {
    int depth = 0;
    StackTraceHeader header;
    await for (final line in stream) {
      final parsedHeader = _parseInstructionsLine(line);
      if (parsedHeader != null) {
        header = parsedHeader;
        depth = 0;
        yield line;
        continue;
      }
      // If at any point we can't get appropriate information for the current
      // line as a stack trace line, then just pass the line through unchanged.
      final lineMatch = _traceLineRE.firstMatch(line);
      final offset = _retrievePCOffset(header, lineMatch);
      final callInfo = offset?.callInfoFrom(_dwarf,
          includeInternalFrames: _includeInternalFrames);
      if (callInfo == null) {
        yield line;
        continue;
      }
      // No lines to output (as this corresponds to Dart internals).
      if (callInfo.isEmpty) continue;
      // Output the lines for the symbolic frame with the prefix found on the
      // original non-symbolic frame line.
      final prefix = line.substring(0, lineMatch.start);
      for (final call in callInfo) {
        yield prefix + _stackTracePiece(call, depth++);
      }
    }
  }
}
