// 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=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("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.
];
