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

import 'dart:async';
import 'dart:developer';
import 'dart:io';

import 'package:front_end/src/api_unstable/util.dart';

import "vm_service_heap_helper.dart" as helper;

Future<void> main(List<String> args) async {
  if (args.contains("--leak")) {
    return doLeak();
  }

  List<helper.Interest> interests = <helper.Interest>[];
  interests.add(
    new helper.Interest(
      Platform.script,
      "LeakMe",
      ["unique"],
    ),
  );
  interests.add(
    new helper.Interest(
      Platform.script,
      "LeakMe2",
      ["uniquePart1", "uniquePart2"],
    ),
  );
  LeakFinderTest heapHelper = new LeakFinderTest(
    interests: interests,
    prettyPrints: [
      new helper.Interest(
        Platform.script,
        "LeakMe",
        ["unique", "forPrettyPrinting"],
      ),
      new helper.Interest(
        Platform.script,
        "LeakMe2",
        ["uniquePart1", "uniquePart2", "forPrettyPrinting"],
      ),
    ],
    throwOnPossibleLeak: false,
  );

  heapHelper.start(
    [
      "--enable-asserts",
      Platform.script.toString(),
      "--leak",
    ],
    stderrReceiver: (s) {},
    stdoutReceiver: (s) {},
  );
  List<String> expectedData = [
    '1: no leak',
    '2: 2: [LeakMe[unique: "a", forPrettyPrinting: "1"], '
        'LeakMe[unique: "a", forPrettyPrinting: "3"]]',
    '3: 2: [LeakMe[unique: "a", forPrettyPrinting: "1"], '
        'LeakMe[unique: "a", forPrettyPrinting: "3"]]',
    '3: 2: [LeakMe[unique: "b", forPrettyPrinting: "2"], '
        'LeakMe[unique: "b", forPrettyPrinting: "4"]]',
    '4: no leak',
    '5: no leak',
    '6: 2: ['
        'LeakMe2[uniquePart1: "a", uniquePart2: "a", forPrettyPrinting: "1"], '
        'LeakMe2[uniquePart1: "a", uniquePart2: "a", forPrettyPrinting: "4"]'
        ']',
  ];
  List<String> leakData = await heapHelper.completer.future;
  if (!equalLists(expectedData, leakData)) {
    throw "Expected and actual not equal:\n\n"
        "- ${expectedData.join("\n- ")}\n\n"
        "vs\n\n"
        "- ${leakData.join("\n- ")}";
  }

  print("Done!");
}

void doLeak() {
  {
    LeakMe a = new LeakMe("a", "1");
    LeakMe b = new LeakMe("b", "2");
    // Expect no leaks.
    debugger();
    LeakMe a2 = new LeakMe("a", "3");
    // Expect one leak: We find leaks for class `LeakMe` based on the first
    // field (`unique`). Now we have two objects with the same data ("a") for
    // this field: `a` and `a2`. That's a leak as we've defined it.
    debugger();
    LeakMe b2 = new LeakMe("b", "4");
    // Expect two leaks: We find leaks for class `LeakMe` based on the first
    // field (`unique`). Now we have two objects with data "a" (`a` and `a2`)
    // and two objects with data "b" (`b` and `b2`).
    debugger();
    print("$a, $b, $a2, $b2");
  }
  {
    LeakMe2 a = new LeakMe2("a", "a", "1");
    LeakMe2 b = new LeakMe2("b", "b", "2");
    // Expect no leaks.
    debugger();
    LeakMe2 a2 = new LeakMe2("a", "foo", "3");
    // Expect no leak.
    debugger();
    LeakMe2 a3 = new LeakMe2("a", "a", "4");
    // Expect one leak: We find leaks for class `LeakMe2` based on the first
    // field AND the second field (`uniquePart1` and `uniquePart2`). Now we have
    // two objects with the same data in both fields ("a" and "a" for part 1 and
    // part 2) namely the objects saved in variables `a` and `a3`.
    // Notice how the object in variable `a2` did not introduce a leak even
    // though part 1 match ("a") as part 2 doesn't ("a" vs "foo").
    debugger();
    print("$a, $b, $a2, $a3");
  }
}

class LeakMe {
  final String unique;
  final String forPrettyPrinting;

  LeakMe(this.unique, this.forPrettyPrinting);
}

class LeakMe2 {
  final String uniquePart1;
  final String uniquePart2;
  final String forPrettyPrinting;

  LeakMe2(this.uniquePart1, this.uniquePart2, this.forPrettyPrinting);
}

class LeakFinderTest extends helper.VMServiceHeapHelperSpecificExactLeakFinder {
  List<String> leakData = [];
  int iterationNumber = -1;
  Completer<List<String>> completer = new Completer<List<String>>();

  LeakFinderTest({
    List<helper.Interest> interests,
    List<helper.Interest> prettyPrints,
    bool throwOnPossibleLeak,
  }) : super(
            interests: interests,
            prettyPrints: prettyPrints,
            throwOnPossibleLeak: throwOnPossibleLeak);

  void processExited(int exitCode) {
    print("Process exited!");
    leakData.sort();
    completer.complete(leakData);
  }

  void leakDetected(String duplicate, int count, List<String> prettyPrints) {
    prettyPrints.sort();
    leakData.add("$iterationNumber: $count: $prettyPrints");
  }

  void noLeakDetected() {
    leakData.add("$iterationNumber: no leak");
  }

  bool shouldDoAnotherIteration(int iterationNumber) {
    this.iterationNumber = iterationNumber;
    return iterationNumber <= 6;
  }
}
