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

// @dart = 2.9

// This test ensures that --trace-precompiler runs without issue and prints
// valid JSON for reasons to retain objects.

// OtherResources=use_dwarf_stack_traces_flag_program.dart

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

import 'package:expect/expect.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('trace-precompiler-flag-test', (String tempDir) async {
    final cwDir = path.dirname(Platform.script.toFilePath());
    // We can just reuse the program for the use_dwarf_stack_traces test.
    final script = path.join(cwDir, '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 every enabled/disabled combination of the
    // following flags that affect object retention:
    final retentionFlags = [
      'retain-function-objects',
      'dwarf-stack-traces-mode'
    ];

    for (var i = 0; i < 1 << retentionFlags.length; i++) {
      final flags = <String>[];
      for (var j = 0; j < retentionFlags.length; j++) {
        final buffer = StringBuffer('--');
        if ((i & (1 << j)) == 0) {
          buffer.write('no-');
        }
        buffer.write(retentionFlags[j]);
        flags.add(buffer.toString());
      }
      await testTracePrecompiler(tempDir, scriptDill, flags);
    }
  });
}

Future<void> testTracePrecompiler(
    String tempDir, String scriptDill, List<String> flags) async {
  final reasonsFile = path.join(tempDir, 'reasons.json');
  final snapshot = path.join(tempDir, 'snapshot.so');
  final result = await run(genSnapshot, <String>[
    ...flags,
    '--write-retained-reasons-to=$reasonsFile',
    '--snapshot-kind=app-aot-elf',
    '--elf=$snapshot',
    scriptDill,
  ]);

  final stream = Stream.fromFuture(File(reasonsFile).readAsString());
  final decisionsJson = await json.decoder.bind(stream).first;
  Expect.isTrue(decisionsJson is List, 'not a list of decisions');
  Expect.isTrue((decisionsJson as List).every((o) => o is Map),
      'not a list of decision objects');
  final decisions = (decisionsJson as List).map((o) => o as Map);
  for (final m in decisions) {
    Expect.isTrue(m.containsKey("name"), 'no name field in decision');
    Expect.isTrue(m["name"] is String, 'name field is not a string');
    Expect.isTrue(m.containsKey("type"), 'no type field in decision');
    Expect.isTrue(m["type"] is String, 'type field is not a string');
    Expect.isTrue(m.containsKey("retained"), 'no retained field in decision');
    Expect.isTrue(m["retained"] is bool, 'retained field is not a boolean');
    if (m["retained"] as bool) {
      Expect.isTrue(m.containsKey("reasons"), 'no reasons field in decision');
      Expect.isTrue(m["reasons"] is List, 'reasons field is not a list');
      final reasons = m["reasons"] as List;
      Expect.isFalse(reasons.isEmpty, 'reasons list should not be empty');
      for (final o in reasons) {
        Expect.isTrue(o is String, 'reason is not a string');
      }
    }
  }
}
