// Copyright (c) 2021, 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_invisible_functions.so

import 'dart:io';

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

import 'dwarf_stack_trace_test.dart' as dwarf_stack_trace_test;

const int LINE_A = 23;
const int LINE_B = 29;
const int LINE_C = 36;
const int LINE_D = 44;
const int LINE_E = 56;

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

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

@pragma("vm:never-inline")
bazz(void Function() func) {
  // Call through tear-off (implicit closure function) which should be
  // omitted from the stack trace.
  func(); // LINE_C
}

class A<T> {
  A();

  @pragma("vm:never-inline")
  void add(T x) {
    bazz(foo); // LINE_D
  }
}

dynamic aa = int.parse('1') == 1 ? A() : [];

Future<void> main() async {
  String rawStack = "";
  try {
    // Dynamic call to a generic-covariant method goes through the
    // dynamic invocation forwarder function, which should be
    // omitted from the stack trace.
    aa.add(42); // LINE_E
  } catch (e, st) {
    rawStack = st.toString();
  }

  if (path.basenameWithoutExtension(Platform.executable) !=
      "dart_precompiled_runtime") {
    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_invisible_functions.so"))!;

  await dwarf_stack_trace_test.checkStackTrace(
      rawStack, dwarf, expectedCallsInfo);
}

final expectedCallsInfo = <List<DartCallInfo>>[
  // Frame 1: 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_invisible_functions_test.dart",
        line: LINE_A,
        column: 3,
        inlined: true),
    DartCallInfo(
        function: "foo",
        filename: "dwarf_stack_trace_invisible_functions_test.dart",
        line: LINE_B,
        column: 3,
        inlined: false)
  ],
  // Frame 2: call to foo in bazz.
  [
    DartCallInfo(
        function: "bazz",
        filename: "dwarf_stack_trace_invisible_functions_test.dart",
        line: LINE_C,
        column: 3,
        inlined: false)
  ],
  // Frame 3: call to bazz in A.method.
  [
    DartCallInfo(
        function: "A.add",
        filename: "dwarf_stack_trace_invisible_functions_test.dart",
        line: LINE_D,
        column: 5,
        inlined: false)
  ],
  // Frame 4: the call to foo in main.
  [
    DartCallInfo(
        function: "main",
        filename: "dwarf_stack_trace_invisible_functions_test.dart",
        line: LINE_E,
        column: 8,
        inlined: false)
  ],
  // Don't assume anything about any of the frames below the main,
  // as this makes the test too brittle.
];
