// Copyright (c) 2020, 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.md file.

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

import "simple_stats.dart";
import "vm_service_helper.dart" as vmService;

const int limit = 10;

Future<void> main(List<String> args) async {
  LeakFinder heapHelper = new LeakFinder();

  await heapHelper.start([
    "--disable-dart-dev",
    "--enable-asserts",
    Platform.script.resolve("incremental_dart2js_tester.dart").toString(),
    "--addDebugBreaks",
    "--fast",
    "--limit=$limit",
  ]);
}

class LeakFinder extends vmService.LaunchingVMServiceHelper {
  @override
  Future<void> run() async {
    vmService.VM vm = await serviceClient.getVM();
    if (vm.isolates!.length != 1) {
      throw "Expected 1 isolate, got ${vm.isolates!.length}";
    }
    vmService.IsolateRef isolateRef = vm.isolates!.single;
    await waitUntilIsolateIsRunnable(isolateRef.id!);
    await serviceClient.resume(isolateRef.id!);

    Map<vmService.ClassRef, List<int>> instanceCounts =
        new Map<vmService.ClassRef, List<int>>();
    Map<vmService.ClassRef, vmService.Class> classInfo =
        new Map<vmService.ClassRef, vmService.Class>();

    Completer<String> cTimeout = new Completer();
    Timer timer = new Timer(new Duration(minutes: 6), () {
      cTimeout.complete("Timeout");
      killProcess();
    });

    Completer<String> cRunDone = new Completer();
    // ignore: unawaited_futures
    runInternal(
        isolateRef,
        classInfo,
        instanceCounts,
        (int iteration) =>
            // Subtract 2 as it's logically one ahead and asks _before_ the run.
            (iteration - 2) > limit ||
            cTimeout.isCompleted ||
            cProcessExited.isCompleted).then((value) {
      cRunDone.complete("Done");
    });

    await Future.any([cRunDone.future, cTimeout.future, cProcessExited.future]);
    timer.cancel();

    print("\n\n======================\n\n");

    findPossibleLeaks(instanceCounts, classInfo);

    // Make sure the process doesn't hang.
    killProcess();
  }

  void findPossibleLeaks(Map<vmService.ClassRef, List<int>> instanceCounts,
      Map<vmService.ClassRef, vmService.Class> classInfo) {
    bool foundLeak = false;
    for (vmService.ClassRef c in instanceCounts.keys) {
      List<int> listOfInstanceCounts = instanceCounts[c]!;

      // Ignore VM internal stuff like "PatchClass", "PcDescriptors" etc.
      // (they don't have a url).
      vmService.Class classDetails = classInfo[c]!;
      String? uriString = classDetails.location?.script?.uri;
      if (uriString == null) continue;

      // For now ignore anything not in package:kernel or package:front_end.
      if (ignoredClass(classDetails)) continue;

      // If they're all equal there's nothing to talk about.
      bool same = true;
      for (int i = 1; i < listOfInstanceCounts.length; i++) {
        if (listOfInstanceCounts[i] != listOfInstanceCounts[0]) {
          same = false;
          break;
        }
      }
      if (same) continue;

      int midPoint = listOfInstanceCounts.length ~/ 2;
      List<int> firstHalf = listOfInstanceCounts.sublist(0, midPoint);
      List<int> secondHalf = listOfInstanceCounts.sublist(midPoint);
      TTestResult ttestResult = SimpleTTestStat.ttest(secondHalf, firstHalf);

      if (!strictClass(classDetails)) {
        if (!ttestResult.significant) continue;

        // TODO(jensj): We could possibly also ignore if it's less (i.e. a
        // negative change), or if the change is < 1%, or the change minus the
        // confidence is < 1% etc.
      }
      print("Differences on ${c.name} (${uriString}): "
          "$listOfInstanceCounts ($ttestResult)");
      foundLeak = true;
    }

    print("\n\n");

    if (foundLeak) {
      print("Possible leak(s) found.");
      print("(Note that this doesn't guarantee that there are any!)");
      exitCode = 1;
    } else {
      print("Didn't identify any leaks.");
      print("(Note that this doesn't guarantee that there are none!)");
      exitCode = 0;
    }
  }

  Future<void> runInternal(
      vmService.IsolateRef isolateRef,
      Map<vmService.ClassRef, vmService.Class> classInfo,
      Map<vmService.ClassRef, List<int>> instanceCounts,
      bool Function(int iteration) shouldBail) async {
    int iterationNumber = 1;
    try {
      while (true) {
        if (shouldBail(iterationNumber)) break;
        if (!await waitUntilPaused(isolateRef.id!)) break;
        print("\n\n====================\n\nIteration #$iterationNumber");
        iterationNumber++;
        vmService.AllocationProfile allocationProfile =
            await forceGC(isolateRef.id!);
        for (vmService.ClassHeapStats member in allocationProfile.members!) {
          if (!classInfo.containsKey(member.classRef)) {
            vmService.Class c = (await serviceClient.getObject(
                isolateRef.id!, member.classRef!.id!)) as vmService.Class;
            classInfo[member.classRef!] = c;
          }
          List<int>? listOfInstanceCounts = instanceCounts[member.classRef];
          if (listOfInstanceCounts == null) {
            listOfInstanceCounts = instanceCounts[member.classRef!] = <int>[];
          }
          while (listOfInstanceCounts.length < iterationNumber - 2) {
            listOfInstanceCounts.add(0);
          }
          listOfInstanceCounts.add(member.instancesCurrent!);
          if (listOfInstanceCounts.length != iterationNumber - 1) {
            throw "Unexpected length";
          }
        }
        await serviceClient.resume(isolateRef.id!);
      }
    } catch (e) {
      print("Got error: $e");
    }
  }

  Completer<String> cProcessExited = new Completer();
  @override
  void processExited(int exitCode) {
    cProcessExited.complete("Exit");
  }

  bool ignoredClass(vmService.Class classDetails) {
    String? uriString = classDetails.location?.script?.uri;
    if (uriString == null) return true;
    if (uriString.startsWith("package:front_end/")) {
      // Classes used for lazy initialization will naturally fluctuate.
      if (classDetails.name == "DillClassBuilder") return true;
      if (classDetails.name == "DillExtensionBuilder") return true;
      if (classDetails.name == "DillExtensionMemberBuilder") return true;
      if (classDetails.name == "DillMemberBuilder") return true;
      if (classDetails.name == "DillTypeAliasBuilder") return true;

      // These classes have proved to fluctuate, although the reason is less
      // clear.
      if (classDetails.name == "InheritedImplementationInterfaceConflict") {
        return true;
      }
      if (classDetails.name == "AbstractMemberOverridingImplementation") {
        return true;
      }
      if (classDetails.name == "VoidTypeBuilder") return true;
      if (classDetails.name == "NamedTypeBuilder") return true;
      if (classDetails.name == "DillClassMember") return true;
      if (classDetails.name == "Scope") return true;
      if (classDetails.name == "ConstructorScope") return true;
      if (classDetails.name == "ScopeBuilder") return true;
      if (classDetails.name == "ConstructorScopeBuilder") return true;
      if (classDetails.name == "NullTypeDeclarationBuilder") return true;
      if (classDetails.name == "NullabilityBuilder") return true;

      return false;
    } else if (uriString.startsWith("package:kernel/")) {
      // DirtifyingList is used for lazy stuff and naturally change in numbers.
      if (classDetails.name == "DirtifyingList") return true;

      // Constants are canonicalized in their compilation run and will thus
      // naturally increase, e.g. we can get 2 more booleans every time (up to
      // a maximum of 2 per library or however many would have been there if we
      // didn't canonicalize at all).
      if (classDetails.name!.endsWith("Constant")) return true;

      // These classes have proved to fluctuate, although the reason is less
      // clear.
      if (classDetails.name == "InterfaceType") return true;

      return false;
    }
    return true;
  }

  // I have commented out the lazy ones below.
  Set<String> frontEndStrictClasses = {
    // "DillClassBuilder",
    // "DillExtensionBuilder",
    // "DillExtensionMemberBuilder",
    "DillLibraryBuilder",
    "DillLoader",
    // "DillMemberBuilder",
    "DillTarget",
    // "DillTypeAliasBuilder",
    "SourceClassBuilder",
    "SourceExtensionBuilder",
    "SourceLibraryBuilder",
    "SourceLoader",
  };

  Set<String> kernelAstStrictClasses = {
    "Class",
    "Constructor",
    "Extension",
    "Field",
    "Library",
    "Procedure",
    "RedirectingFactory",
    "Typedef",
  };

  bool strictClass(vmService.Class classDetails) {
    if (!kernelAstStrictClasses.contains(classDetails.name) &&
        !frontEndStrictClasses.contains(classDetails.name)) return false;

    if (kernelAstStrictClasses.contains(classDetails.name) &&
        classDetails.location?.script?.uri == "package:kernel/ast.dart") {
      return true;
    }
    if (frontEndStrictClasses.contains(classDetails.name) &&
        classDetails.location?.script?.uri?.startsWith("package:front_end/") ==
            true) {
      return true;
    }

    throw "$classDetails: ${classDetails.name} --- ${classDetails.location}";
  }
}
