// Copyright (c) 2017, 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.

// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf.so

import 'dart:convert';
import 'dart:io';

import 'package:expect/config.dart';
import 'package:expect/expect.dart';
import 'package:native_stack_traces/native_stack_traces.dart';
import 'package:path/path.dart' as path;

@pragma("vm:prefer-inline")
bar() {
  // Keep the 'throw' and its argument on separate lines.
  throw // force linebreak with dart format
  "Hello, Dwarf!";
}

@pragma("vm:never-inline")
foo() {
  bar();
}

Future<void> main() async {
  String rawStack = "";
  try {
    foo();
  } catch (e, st) {
    rawStack = st.toString();
  }

  if (!isVmAotConfiguration) {
    return; // Not running from an AOT compiled snapshot.
  }

  if (Platform.isAndroid) {
    return; // Generated dwarf.so not available on the test device.
  }

  final dwarf = Dwarf.fromFile(
    path.join(Platform.environment["TEST_COMPILATION_DIR"]!, "dwarf.so"),
  )!;

  await checkStackTrace(rawStack, dwarf, expectedCallsInfo);
}

Future<void> checkStackTrace(
  String rawStack,
  Dwarf dwarf,
  List<List<DartCallInfo>> expectedCallsInfo,
) async {
  print("");
  print("Raw stack trace:");
  print(rawStack);

  final rawLines = await Stream.value(
    rawStack,
  ).transform(const LineSplitter()).toList();

  final pcOffsets = collectPCOffsets(rawLines).toList();
  Expect.isNotEmpty(pcOffsets);

  print('PCOffsets:');
  for (final offset in pcOffsets) {
    print('* $offset');
  }
  print('');

  // We should have at least enough PC addresses to cover the frames we'll be
  // checking.
  Expect.isTrue(pcOffsets.length >= expectedCallsInfo.length);

  final isolateStart = dwarf.isolateStartAddress(pcOffsets.first.architecture);
  Expect.isNotNull(isolateStart);
  print('Isolate start offset: 0x${isolateStart!.toRadixString(16)}');

  // The addresses of the stack frames in the separate DWARF debugging info.
  final virtualAddresses = pcOffsets
      .map((o) => dwarf.virtualAddressOf(o))
      .toList();

  print('Virtual addresses from PCOffsets:');
  for (final address in virtualAddresses) {
    print('* 0x${address.toRadixString(16)}');
  }
  print('');

  // Some double-checks using other information in the non-symbolic stack trace.
  final dsoBase = dsoBaseAddresses(rawLines).single;
  print('DSO base address: 0x${dsoBase.toRadixString(16)}');

  final absoluteIsolateStart = isolateStartAddresses(rawLines).single;
  print(
    'Absolute isolate start address: '
    '0x${absoluteIsolateStart.toRadixString(16)}',
  );

  final absolutes = absoluteAddresses(rawLines);
  // The relocated addresses of the stack frames in the loaded DSO. These is
  // only guaranteed to be the same as virtualAddresses if the built-in ELF
  // generator was used to create the snapshot.
  final relocatedAddresses = absolutes.map((a) => a - dsoBase);

  print('Relocated absolute addresses:');
  for (final address in relocatedAddresses) {
    print('* 0x${address.toRadixString(16)}');
  }
  print('');

  // Explicits will be empty if not generating ELF snapshots directly, which
  // means we can't depend on virtual addresses in the snapshot lining up with
  // those in the separate debugging information.
  final explicits = explicitVirtualAddresses(rawLines);
  if (explicits.isNotEmpty) {
    print('Explicit virtual addresses:');
    for (final address in explicits) {
      print('* 0x${address.toRadixString(16)}');
    }
    print('');
    // Direct-to-ELF snapshots should have a build ID.
    Expect.isNotNull(dwarf.buildId);
    Expect.deepEquals(explicits, virtualAddresses);

    // This is an ELF snapshot, so check that these two are the same.
    Expect.deepEquals(virtualAddresses, relocatedAddresses);
  }

  final gotCallsInfo = <List<DartCallInfo>>[];

  for (final offset in pcOffsets) {
    final externalCallInfo = dwarf.callInfoForPCOffset(offset);
    Expect.isNotNull(externalCallInfo);
    final allCallInfo = dwarf.callInfoForPCOffset(
      offset,
      includeInternalFrames: true,
    );
    Expect.isNotNull(allCallInfo);
    for (final call in externalCallInfo!) {
      Expect.isTrue(call is DartCallInfo, "got non-Dart call info ${call}");
      Expect.isFalse(call.isInternal);
      Expect.isTrue(
        allCallInfo!.contains(call),
        "External call info ${call} is not among all calls",
      );
    }
    for (final call in allCallInfo!) {
      if (!call.isInternal) {
        Expect.isTrue(
          externalCallInfo.contains(call),
          "External call info ${call} is not among external calls",
        );
      }
    }
    gotCallsInfo.add(externalCallInfo.cast<DartCallInfo>().toList());
  }

  print("");
  print("Call information for PC addresses:");
  for (var i = 0; i < virtualAddresses.length; i++) {
    print("For PC 0x${virtualAddresses[i].toRadixString(16)}:");
    print("  Calls corresponding to user or library code:");
    gotCallsInfo[i].forEach((frame) => print("    ${frame}"));
  }

  // Remove empty entries which correspond to skipped internal frames.
  gotCallsInfo.removeWhere((calls) => calls.isEmpty);

  checkFrames(gotCallsInfo, expectedCallsInfo);

  final gotSymbolizedLines = await Stream.fromIterable(rawLines)
      .transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: false))
      .toList();

  final gotSymbolizedCalls = gotSymbolizedLines
      .where((s) => s.startsWith('#'))
      .toList();

  print("");
  print("Symbolized stack trace:");
  gotSymbolizedLines.forEach(print);
  print("");
  print("Extracted calls:");
  gotSymbolizedCalls.forEach(print);

  final expectedStrings = extractCallStrings(expectedCallsInfo);
  // There are two strings in the list for each line in the output.
  final expectedCallCount = expectedStrings.length ~/ 2;

  Expect.isTrue(gotSymbolizedCalls.length >= expectedCallCount);

  // Strip off any unexpected lines, so we can also make sure we didn't get
  // unexpected calls prior to those calls we expect.
  final gotCallsTrace = gotSymbolizedCalls
      .sublist(0, expectedCallCount)
      .join('\n');

  Expect.containsInOrder(expectedStrings, gotCallsTrace);
}

final expectedCallsInfo = <List<DartCallInfo>>[
  // The first frame should correspond to the throw in bar, which was inlined
  // into foo (so we'll get information for two calls for that PC address).
  [
    DartCallInfo(
      function: "bar",
      filename: "dwarf_stack_trace_test.dart",
      line: 17,
      column: 3,
      inlined: true,
    ),
    DartCallInfo(
      function: "foo",
      filename: "dwarf_stack_trace_test.dart",
      line: 23,
      column: 3,
      inlined: false,
    ),
  ],
  // The second frame corresponds to call to foo in main.
  [
    DartCallInfo(
      function: "main",
      filename: "dwarf_stack_trace_test.dart",
      line: 29,
      column: 5,
      inlined: false,
    ),
  ],
  // Don't assume anything about any of the frames below the call to foo
  // in main, as this makes the test too brittle.
];

void checkFrames(
  List<List<DartCallInfo>> gotInfo,
  List<List<DartCallInfo>> expectedInfo,
) {
  // There may be frames below those we check.
  Expect.isTrue(gotInfo.length >= expectedInfo.length);

  // We can't just use deep equality, since we only have the filenames in the
  // expected version, not the whole path, and we don't really care if
  // non-positive line numbers match, as long as they're both non-positive.
  for (var i = 0; i < expectedInfo.length; i++) {
    for (var j = 0; j < expectedInfo[i].length; j++) {
      final got = gotInfo[i][j];
      final expected = expectedInfo[i][j];
      Expect.equals(expected.function, got.function);
      Expect.equals(expected.inlined, got.inlined);
      Expect.equals(expected.filename, path.basename(got.filename));
      if (expected.isInternal) {
        Expect.isTrue(got.isInternal);
      } else {
        Expect.equals(expected.line, got.line);
      }
    }
  }
}

List<String> extractCallStrings(List<List<CallInfo>> expectedCalls) {
  var ret = <String>[];
  for (final frame in expectedCalls) {
    for (final call in frame) {
      if (call is DartCallInfo) {
        ret.add(call.function);
        if (call.isInternal) {
          ret.add("${call.filename}:??");
        } else {
          ret.add("${call.filename}:${call.line}");
        }
      }
    }
  }
  return ret;
}

Iterable<int> parseUsingAddressRegExp(RegExp re, Iterable<String> lines) sync* {
  for (final line in lines) {
    final match = re.firstMatch(line);
    if (match == null) continue;
    final s = match.group(1);
    if (s == null) continue;
    yield int.parse(s, radix: 16);
  }
}

final _absRE = RegExp(r'abs ([a-f\d]+)');

Iterable<int> absoluteAddresses(Iterable<String> lines) =>
    parseUsingAddressRegExp(_absRE, lines);

final _virtRE = RegExp(r'virt ([a-f\d]+)');

Iterable<int> explicitVirtualAddresses(Iterable<String> lines) =>
    parseUsingAddressRegExp(_virtRE, lines);

final _dsoBaseRE = RegExp(r'isolate_dso_base: ([a-f\d]+)');

Iterable<int> dsoBaseAddresses(Iterable<String> lines) =>
    parseUsingAddressRegExp(_dsoBaseRE, lines);

final _isolateStartRE = RegExp(r'isolate_instructions: ([a-f\d]+)');

Iterable<int> isolateStartAddresses(Iterable<String> lines) =>
    parseUsingAddressRegExp(_isolateStartRE, lines);
