// 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.

// This test ensures that the flag for --dwarf-stack-traces given at AOT
// compile-time will be used at runtime (irrespective if other values were
// passed to the runtime).

import "dart:async";
import "dart:convert";
import "dart:io";

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

import 'use_flag_test_helper.dart';

main(List<String> args) async {
  if (!isAOTRuntime) {
    return; // Running in JIT: AOT binaries not available.
  }

  if (Platform.isAndroid) {
    return; // SDK tree and dart_bootstrap not available on the test device.
  }

  // These are the tools we need to be available to run on a given platform:
  if (!await testExecutable(genSnapshot)) {
    throw "Cannot run test as $genSnapshot not available";
  }
  if (!await testExecutable(aotRuntime)) {
    throw "Cannot run test as $aotRuntime not available";
  }
  if (!File(platformDill).existsSync()) {
    throw "Cannot run test as $platformDill does not exist";
  }

  await withTempDir('dwarf-flag-test', (String tempDir) async {
    // We have to use the program in its original location so it can use
    // the dart:_internal library (as opposed to adding it as an OtherResources
    // option to the test).
    final script = path.join(sdkDir, 'runtime', 'tests', 'vm', 'dart',
        'use_dwarf_stack_traces_flag_program.dart');
    final scriptDill = path.join(tempDir, 'flag_program.dill');

    // Compile script to Kernel IR.
    await run(genKernel, <String>[
      '--aot',
      '--platform=$platformDill',
      '-o',
      scriptDill,
      script,
    ]);

    // Run the AOT compiler with/without Dwarf stack traces.
    final scriptDwarfSnapshot = path.join(tempDir, 'dwarf.so');
    final scriptNonDwarfSnapshot = path.join(tempDir, 'non_dwarf.so');
    final scriptDwarfDebugInfo = path.join(tempDir, 'debug_info.so');
    await Future.wait(<Future>[
      run(genSnapshot, <String>[
        // We test --dwarf-stack-traces-mode, not --dwarf-stack-traces, because
        // the latter is a handler that sets the former and also may change
        // other flags. This way, we limit the difference between the two
        // snapshots and also directly test the flag saved as a VM global flag.
        '--dwarf-stack-traces-mode',
        '--save-debugging-info=$scriptDwarfDebugInfo',
        '--snapshot-kind=app-aot-elf',
        '--elf=$scriptDwarfSnapshot',
        scriptDill,
      ]),
      run(genSnapshot, <String>[
        '--no-dwarf-stack-traces-mode',
        '--snapshot-kind=app-aot-elf',
        '--elf=$scriptNonDwarfSnapshot',
        scriptDill,
      ]),
    ]);

    // Run the resulting Dwarf-AOT compiled script.

    final output1 = await runTestProgram(aotRuntime,
        <String>['--dwarf-stack-traces-mode', scriptDwarfSnapshot, scriptDill]);
    final output2 = await runTestProgram(aotRuntime, <String>[
      '--no-dwarf-stack-traces-mode',
      scriptDwarfSnapshot,
      scriptDill
    ]);

    // Run the resulting non-Dwarf-AOT compiled script.
    final nonDwarfTrace1 = (await runTestProgram(aotRuntime, <String>[
      '--dwarf-stack-traces-mode',
      scriptNonDwarfSnapshot,
      scriptDill,
    ]))
        .trace;
    final nonDwarfTrace2 = (await runTestProgram(aotRuntime, <String>[
      '--no-dwarf-stack-traces-mode',
      scriptNonDwarfSnapshot,
      scriptDill,
    ]))
        .trace;

    // Ensure the result is based off the flag passed to gen_snapshot, not
    // the one passed to the runtime.
    Expect.deepEquals(nonDwarfTrace1, nonDwarfTrace2);

    // Check with DWARF from separate debugging information.
    await compareTraces(nonDwarfTrace1, output1, output2, scriptDwarfDebugInfo);
    // Check with DWARF in generated snapshot.
    await compareTraces(nonDwarfTrace1, output1, output2, scriptDwarfSnapshot);

    // Currently there are no appropriate buildtools on the simulator trybots as
    // normally they compile to ELF and don't need them for compiling assembly
    // snapshots.
    if ((Platform.isLinux || Platform.isMacOS) && !isSimulator) {
      final scriptAssembly = path.join(tempDir, 'dwarf_assembly.S');
      final scriptDwarfAssemblyDebugInfo =
          path.join(tempDir, 'dwarf_assembly_info.so');
      final scriptDwarfAssemblySnapshot =
          path.join(tempDir, 'dwarf_assembly.so');
      // We get a separate .dSYM bundle on MacOS.
      final scriptDwarfAssemblyDebugSnapshot =
          scriptDwarfAssemblySnapshot + (Platform.isMacOS ? '.dSYM' : '');

      await run(genSnapshot, <String>[
        // We test --dwarf-stack-traces-mode, not --dwarf-stack-traces, because
        // the latter is a handler that sets the former and also may change
        // other flags. This way, we limit the difference between the two
        // snapshots and also directly test the flag saved as a VM global flag.
        '--dwarf-stack-traces-mode',
        '--save-debugging-info=$scriptDwarfAssemblyDebugInfo',
        '--snapshot-kind=app-aot-assembly',
        '--assembly=$scriptAssembly',
        scriptDill,
      ]);

      await assembleSnapshot(scriptAssembly, scriptDwarfAssemblySnapshot,
          debug: true);

      // Run the resulting Dwarf-AOT compiled script.
      final assemblyOutput1 = await runTestProgram(aotRuntime, <String>[
        '--dwarf-stack-traces-mode',
        scriptDwarfAssemblySnapshot,
        scriptDill,
      ]);
      final assemblyOutput2 = await runTestProgram(aotRuntime, <String>[
        '--no-dwarf-stack-traces-mode',
        scriptDwarfAssemblySnapshot,
        scriptDill,
      ]);

      // Check with DWARF in assembled snapshot.
      await compareTraces(nonDwarfTrace1, assemblyOutput1, assemblyOutput2,
          scriptDwarfAssemblyDebugSnapshot,
          fromAssembly: true);
      // Check with DWARF from separate debugging information.
      await compareTraces(nonDwarfTrace1, assemblyOutput1, assemblyOutput2,
          scriptDwarfAssemblyDebugInfo,
          fromAssembly: true);
    }
  });
}

class DwarfTestOutput {
  final List<String> trace;
  final int allocateObjectInstructionsOffset;

  DwarfTestOutput(this.trace, this.allocateObjectInstructionsOffset);
}

Future<void> compareTraces(List<String> nonDwarfTrace, DwarfTestOutput output1,
    DwarfTestOutput output2, String dwarfPath,
    {bool fromAssembly = false}) async {
  // For DWARF stack traces, we can't guarantee that the stack traces are
  // textually equal on all platforms, but if we retrieve the PC offsets
  // out of the stack trace, those should be equal.
  final tracePCOffsets1 = collectPCOffsets(output1.trace);
  final tracePCOffsets2 = collectPCOffsets(output2.trace);
  Expect.deepEquals(tracePCOffsets1, tracePCOffsets2);

  // Check that translating the DWARF stack trace (without internal frames)
  // matches the symbolic stack trace.
  print("Reading DWARF info from ${dwarfPath}");
  final dwarf = Dwarf.fromFile(dwarfPath);
  Expect.isNotNull(dwarf);

  // Check that build IDs match for traces from running ELF snapshots.
  if (!fromAssembly) {
    Expect.isNotNull(dwarf!.buildId);
    print('Dwarf build ID: "${dwarf.buildId!}"');
    // We should never generate an all-zero build ID.
    Expect.notEquals(dwarf.buildId, "00000000000000000000000000000000");
    // This is a common failure case as well, when HashBitsContainer ends up
    // hashing over seemingly empty sections.
    Expect.notEquals(dwarf.buildId, "01000000010000000100000001000000");
    final buildId1 = buildId(output1.trace);
    Expect.isFalse(buildId1.isEmpty);
    print('Trace 1 build ID: "${buildId1}"');
    Expect.equals(dwarf.buildId, buildId1);
    final buildId2 = buildId(output2.trace);
    Expect.isFalse(buildId2.isEmpty);
    print('Trace 2 build ID: "${buildId2}"');
    Expect.equals(dwarf.buildId, buildId2);
  }

  final decoder = DwarfStackTraceDecoder(dwarf!);
  final translatedDwarfTrace1 =
      await Stream.fromIterable(output1.trace).transform(decoder).toList();

  final allocateObjectPCOffset1 = PCOffset(
      output1.allocateObjectInstructionsOffset, InstructionsSection.isolate);
  final allocateObjectPCOffset2 = PCOffset(
      output2.allocateObjectInstructionsOffset, InstructionsSection.isolate);

  print('Offset of first stub address is $allocateObjectPCOffset1');
  print('Offset of second stub address is $allocateObjectPCOffset2');

  final allocateObjectRelocatedAddress1 =
      dwarf.virtualAddressOf(allocateObjectPCOffset1);
  final allocateObjectRelocatedAddress2 =
      dwarf.virtualAddressOf(allocateObjectPCOffset2);

  final allocateObjectCallInfo1 = dwarf.callInfoFor(
      allocateObjectRelocatedAddress1,
      includeInternalFrames: true);
  final allocateObjectCallInfo2 = dwarf.callInfoFor(
      allocateObjectRelocatedAddress2,
      includeInternalFrames: true);

  Expect.isNotNull(allocateObjectCallInfo1);
  Expect.isNotNull(allocateObjectCallInfo2);
  Expect.equals(allocateObjectCallInfo1!.length, 1);
  Expect.equals(allocateObjectCallInfo2!.length, 1);
  Expect.isTrue(
      allocateObjectCallInfo1.first is StubCallInfo, 'is not a StubCall');
  Expect.isTrue(
      allocateObjectCallInfo2.first is StubCallInfo, 'is not a StubCall');
  final stubCall1 = allocateObjectCallInfo1.first as StubCallInfo;
  final stubCall2 = allocateObjectCallInfo2.first as StubCallInfo;
  Expect.equals(stubCall1.name, stubCall2.name);
  Expect.contains('AllocateObject', stubCall1.name);
  Expect.contains('AllocateObject', stubCall2.name);

  print("Successfully matched AllocateObject stub addresses");
  print("");

  final translatedStackFrames = onlySymbolicFrameLines(translatedDwarfTrace1);
  final originalStackFrames = onlySymbolicFrameLines(nonDwarfTrace);

  print('Stack frames from translated non-symbolic stack trace:');
  translatedStackFrames.forEach(print);
  print('');

  print('Stack frames from original symbolic stack trace:');
  originalStackFrames.forEach(print);
  print('');

  Expect.isTrue(translatedStackFrames.length > 0);
  Expect.isTrue(originalStackFrames.length > 0);

  // In symbolic mode, we don't store column information to avoid an increase
  // in size of CodeStackMaps. Thus, we need to strip any columns from the
  // translated non-symbolic stack to compare them via equality.
  final columnStrippedTranslated = removeColumns(translatedStackFrames);

  print('Stack frames from translated non-symbolic stack trace, no columns:');
  columnStrippedTranslated.forEach(print);
  print('');

  Expect.deepEquals(columnStrippedTranslated, originalStackFrames);

  // Since we compiled directly to ELF, there should be a DSO base address
  // in the stack trace header and 'virt' markers in the stack frames.

  // The offsets of absolute addresses from their respective DSO base
  // should be the same for both traces.
  final dsoBase1 = dsoBaseAddresses(output1.trace).single;
  final dsoBase2 = dsoBaseAddresses(output2.trace).single;

  final absTrace1 = absoluteAddresses(output1.trace);
  final absTrace2 = absoluteAddresses(output2.trace);

  final relocatedFromDso1 = absTrace1.map((a) => a - dsoBase1);
  final relocatedFromDso2 = absTrace2.map((a) => a - dsoBase2);

  Expect.deepEquals(relocatedFromDso1, relocatedFromDso2);

  // We don't print 'virt' relocated addresses when running assembled snapshots.
  if (fromAssembly) return;

  // The relocated addresses marked with 'virt' should match between the
  // different runs, and they should also match the relocated address
  // calculated from the PCOffset for each frame as well as the relocated
  // address for each frame calculated using the respective DSO base.
  final virtTrace1 = explicitVirtualAddresses(output1.trace);
  final virtTrace2 = explicitVirtualAddresses(output2.trace);

  Expect.deepEquals(virtTrace1, virtTrace2);

  Expect.deepEquals(
      virtTrace1, tracePCOffsets1.map((o) => o.virtualAddressIn(dwarf)));
  Expect.deepEquals(
      virtTrace2, tracePCOffsets2.map((o) => o.virtualAddressIn(dwarf)));

  Expect.deepEquals(virtTrace1, relocatedFromDso1);
  Expect.deepEquals(virtTrace2, relocatedFromDso2);
}

Future<DwarfTestOutput> runTestProgram(
    String executable, List<String> args) async {
  final result = await runHelper(executable, args);

  if (result.exitCode == 0) {
    throw 'Command did not fail with non-zero exit code';
  }
  Expect.isTrue(result.stdout.isNotEmpty);
  Expect.isTrue(result.stderr.isNotEmpty);

  return DwarfTestOutput(
      LineSplitter.split(result.stderr).toList(), int.parse(result.stdout));
}

final _buildIdRE = RegExp(r"build_id: '([a-f\d]+)'");
String buildId(Iterable<String> lines) {
  for (final line in lines) {
    final match = _buildIdRE.firstMatch(line);
    if (match != null) {
      return match.group(1)!;
    }
  }
  return '';
}

final _symbolicFrameRE = RegExp(r'^#\d+\s+');

Iterable<String> onlySymbolicFrameLines(Iterable<String> lines) {
  return lines.where((line) => _symbolicFrameRE.hasMatch(line));
}

final _columnsRE = RegExp(r'[(](.*:\d+):\d+[)]');

Iterable<String> removeColumns(Iterable<String> lines) sync* {
  for (final line in lines) {
    final match = _columnsRE.firstMatch(line);
    if (match != null) {
      yield line.replaceRange(match.start, match.end, '(${match.group(1)!})');
    } else {
      yield line;
    }
  }
}

Iterable<int> parseUsingAddressRegExp(RegExp re, Iterable<String> lines) sync* {
  for (final line in lines) {
    final match = re.firstMatch(line);
    if (match != null) {
      yield int.parse(match.group(1)!, 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);
