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

import "vm_service_helper.dart" as vmService;

class VMServiceHeapHelperSpecificExactLeakFinder
    extends vmService.LaunchingVMServiceHelper {
  final Set _interestsClassNames = {};
  final Map<Uri, Map<String, List<String>>> _interests = {};
  final Map<Uri, Map<String, List<String>>> _prettyPrints = {};
  final Set<String> _shouldAlwaysFind = {};
  final bool throwOnPossibleLeak;
  bool verbose = false;
  int? timeout;

  VMServiceHeapHelperSpecificExactLeakFinder({
    List<Interest> interests = const [],
    List<Interest> prettyPrints = const [],
    this.throwOnPossibleLeak = false,
  }) {
    if (interests.isEmpty) throw "Empty list of interests given";
    for (Interest interest in interests) {
      if (interest.expectToAlwaysFind) {
        _shouldAlwaysFind.add("${interest.uri}|${interest.className}");
      }
      Map<String, List<String>>? classToFields = _interests[interest.uri];
      if (classToFields == null) {
        classToFields = Map<String, List<String>>();
        _interests[interest.uri] = classToFields;
      }
      _interestsClassNames.add(interest.className);
      List<String>? fields = classToFields[interest.className];
      if (fields == null) {
        fields = <String>[];
        classToFields[interest.className] = fields;
      }
      fields.addAll(interest.fieldNames);
    }
    for (Interest interest in prettyPrints) {
      Map<String, List<String>>? classToFields = _prettyPrints[interest.uri];
      if (classToFields == null) {
        classToFields = Map<String, List<String>>();
        _prettyPrints[interest.uri] = classToFields;
      }
      List<String>? fields = classToFields[interest.className];
      if (fields == null) {
        fields = <String>[];
        classToFields[interest.className] = fields;
      }
      fields.addAll(interest.fieldNames);
    }
  }

  Future<void> pause() async {
    await serviceClient.pause(_isolateRef.id!);
  }

  late vmService.VM _vm;
  late vmService.IsolateRef _isolateRef;
  late int _iterationNumber;
  int get iterationNumber => _iterationNumber;

  /// Best effort check if the isolate is idle.
  Future<bool> isIdle() async {
    dynamic tmp = await serviceClient.getIsolate(_isolateRef.id!);
    if (tmp is vmService.Isolate) {
      vmService.Isolate isolate = tmp;
      return isolate.pauseEvent!.topFrame == null;
    }
    return false;
  }

  bool _processHasExited = false;

  @override
  void processExited(int exitCode) {
    super.processExited(exitCode);
    _processHasExited = true;
  }

  @override
  Future<void> run() async {
    _vm = await serviceClient.getVM();
    if (_vm.isolates!.length == 0) {
      print("Didn't get any isolates. Will wait 1 second and retry.");
      await Future.delayed(new Duration(seconds: 1));
      _vm = await serviceClient.getVM();
    }
    if (_vm.isolates!.length != 1) {
      throw "Expected 1 isolate, got ${_vm.isolates!.length}";
    }
    _isolateRef = _vm.isolates!.single;
    await forceGC(_isolateRef.id!);

    assert(await isPausedAtStart(_isolateRef.id!));
    await serviceClient.resume(_isolateRef.id!);

    _iterationNumber = 1;
    while (true) {
      if (!shouldDoAnotherIteration(_iterationNumber)) break;
      {
        Future<bool> f = waitUntilPaused(_isolateRef.id!);
        if (timeout != null) {
          f = f.timeout(new Duration(seconds: timeout!));
        }
        try {
          await f;
        } catch (e) {
          await Future.delayed(const Duration(seconds: 2));
          if (_processHasExited) {
            // Seems OK for it to have thrown when the process exited
            break;
          }
          // Process is still alive so don't swallow the throw.
          rethrow;
        }
      }
      print("Iteration: #$_iterationNumber");

      Stopwatch stopwatch = new Stopwatch()..start();

      vmService.AllocationProfile allocationProfile = await forceGC(
        _isolateRef.id!,
      );
      print("Forced GC in ${stopwatch.elapsedMilliseconds} ms");

      stopwatch.reset();
      List<Leak> leaks = [];
      Set<String> leftToAlwaysFind = _shouldAlwaysFind.toSet();
      for (vmService.ClassHeapStats member in allocationProfile.members!) {
        if (_interestsClassNames.contains(member.classRef!.name)) {
          String? libraryId = member.classRef?.library?.id;
          if (libraryId == null) continue;
          vmService.Library library =
              (await serviceClient.getObject(_isolateRef.id!, libraryId))
                  as vmService.Library;
          String? importUriString = library.uri;
          if (importUriString == null) continue;
          String? classId = member.classRef?.id;
          if (classId == null) continue;
          vmService.Class c =
              (await serviceClient.getObject(_isolateRef.id!, classId))
                  as vmService.Class;
          String? partUriString = c.location?.script?.uri;
          if (partUriString == null) continue;
          String? className = c.name;
          if (className == null) continue;

          (List<String>, List<String>)? fieldsData =
              _getFieldsForClassAndPrettyPrint(partUriString, className) ??
              _getFieldsForClassAndPrettyPrint(importUriString, className);
          if (fieldsData == null) continue;
          List<String> fieldsForClass = fieldsData.$1;
          List<String> fieldsForClassPrettyPrint = fieldsData.$2;

          if (member.instancesCurrent != 0) {
            leftToAlwaysFind.remove("$partUriString|$className");
            leftToAlwaysFind.remove("$importUriString|$className");
            if (verbose) {
              print(
                "Has ${member.instancesCurrent} instances of "
                "${member.classRef!.name}",
              );
            }

            leaks.addAll(
              await _findLeaks(
                _isolateRef,
                member.classRef!,
                fieldsForClass,
                fieldsForClassPrettyPrint,
              ),
            );
          }
        }
      }
      if (leaks.isNotEmpty) {
        for (Leak leak in leaks) {
          leakDetected(leak.duplicate, leak.count, leak.prettyPrints);
        }
        if (throwOnPossibleLeak) {
          throw "Leaks found";
        }
      } else {
        noLeakDetected();
      }
      if (leftToAlwaysFind.isNotEmpty) {
        throw "Expected to find, but didn't: $leftToAlwaysFind";
      }

      print("Looked for leaks in ${stopwatch.elapsedMilliseconds} ms");

      {
        Future<vmService.Success> f = serviceClient.resume(_isolateRef.id!);
        if (timeout != null) {
          f = f.timeout(new Duration(seconds: timeout!));
        }
        await f;
      }

      _iterationNumber++;
    }
  }

  (List<String>, List<String>)? _getFieldsForClassAndPrettyPrint(
    String uriString,
    String className,
  ) {
    Uri uri = Uri.parse(uriString);
    Map<String, List<String>>? uriInterest = _interests[uri];
    if (uriInterest == null) return null;
    List<String>? fieldsForClass = uriInterest[className];
    if (fieldsForClass == null) return null;

    List<String> fieldsForClassPrettyPrint = fieldsForClass;
    uriInterest = _prettyPrints[uri];
    if (uriInterest != null && uriInterest[className] != null) {
      fieldsForClassPrettyPrint = uriInterest[className]!;
    }
    return (fieldsForClass, fieldsForClassPrettyPrint);
  }

  Future<List<Leak>> _findLeaks(
    vmService.IsolateRef isolateRef,
    vmService.ClassRef classRef,
    List<String> fieldsForClass,
    List<String> fieldsForClassPrettyPrint,
  ) async {
    vmService.InstanceRef instancesAsList = (await serviceClient
        .getInstancesAsList(
          isolateRef.id!,
          classRef.id!,
          includeSubclasses: false,
          includeImplementers: false,
        ));

    // Create dart code that `toString`s a class instance according to
    // the fields given as wanting printed. Both for finding duplicates (1) and
    // for pretty printing entries (for instance to be able to differentiate
    // them) (2).

    // 1:
    String fieldsToStringCode =
        classRef.name! +
        "[" +
        fieldsForClass
            .map((value) => "$value: \"\${element.$value}\"")
            .join(", ") +
        "]";
    // 2:
    String fieldsToStringPrettyPrintCode =
        classRef.name! +
        "[" +
        fieldsForClassPrettyPrint
            .map((value) => "$value: \"\${element.$value}\"")
            .join(", ") +
        "]";

    // Expression evaluation to find duplicates: Put all entries into a map
    // indexed by the `toString` code created above, mapping to list of that
    // data.
    vmService.InstanceRef mappedData =
        (await serviceClient.evaluate(isolateRef.id!, instancesAsList.id!, """
          this
              .fold({}, (dynamic index, dynamic element) {
                String key = '$fieldsToStringCode';
                var list = index[key] ??= [];
                list.add(element);
                return index;
              })
        """))
            as vmService.InstanceRef;
    // Expression calculation to find if any of the lists created as values
    // above contains more than one entry (i.e. there's a duplicate).
    vmService.InstanceRef duplicatesLengthRef =
        (await serviceClient.evaluate(isolateRef.id!, mappedData.id!, """
          this
              .values
              .where((dynamic element) => (element.length > 1) as bool)
              .length
        """))
            as vmService.InstanceRef;
    vmService.Instance duplicatesLength =
        (await serviceClient.getObject(isolateRef.id!, duplicatesLengthRef.id!))
            as vmService.Instance;
    int? duplicates = int.tryParse(duplicatesLength.valueAsString!);
    if (duplicates != 0) {
      // There are duplicates. Expression calculation to encode the duplication
      // data (both the string that caused it to be a duplicate and the pretty
      // prints) as a string (to be able to easily get a hold of it here).
      // It filters out the duplicates and then encodes it with a simple scheme
      // of length-prefixed strings (and with everything separated by colons),
      // e.g. encode the string "string" as "6:string" (length 6, string),
      // and the list ["foo", "bar"] as "2:3:foo:3:bar" (2 entries, length 3,
      // foo, length 3, bar).
      vmService.ObjRef duplicatesDataRef =
          (await serviceClient.evaluate(isolateRef.id!, mappedData.id!, """
          this
              .entries
              .where((element) => (element.value as List).length > 1)
              .map((dynamic e) {
            var keyPart = "\${e.key.length}:\${e.key}";
            List value = e.value as List;
            var valuePart1 = "\${value.length}";
            var valuePart2 = value
                .map((element) => '$fieldsToStringPrettyPrintCode')
                .map((element) => "\${element.length}:\$element")
                .join(":");
            return "\${keyPart}:\${valuePart1}:\${valuePart2}";
          }).join(":")
          """))
              as vmService.ObjRef;
      if (duplicatesDataRef is! vmService.InstanceRef) {
        if (duplicatesDataRef is vmService.ErrorRef) {
          vmService.Error error =
              (await serviceClient.getObject(
                    isolateRef.id!,
                    duplicatesDataRef.id!,
                  ))
                  as vmService.Error;
          throw "Leak found, but trying to evaluate pretty printing "
              "didn't go as planned.\n"
              "Got error with message "
              "'${error.message}'";
        } else {
          throw "Leak found, but trying to evaluate pretty printing "
              "didn't go as planned.\n"
              "Got type '${duplicatesDataRef.runtimeType}':"
              "$duplicatesDataRef";
        }
      }

      vmService.Instance duplicatesData =
          (await serviceClient.getObject(isolateRef.id!, duplicatesDataRef.id!))
              as vmService.Instance;
      String encodedData = duplicatesData.valueAsString!;
      try {
        return parseEncodedLeakString(encodedData);
      } catch (e) {
        print("Failure on decoding '$encodedData'");
        rethrow;
      }
    } else {
      // No leaks.
      return [];
    }
  }

  static List<Leak> parseEncodedLeakString(String leakString) {
    int index = 0;
    int parseInt() {
      int endPartIndex = leakString.indexOf(":", index);
      String part = leakString.substring(index, endPartIndex);
      int value = int.parse(part);
      index = endPartIndex + 1;
      return value;
    }

    String parseString() {
      int value = parseInt();
      String string = leakString.substring(index, index + value);
      index = index + value + 1;
      return string;
    }

    List<Leak> result = [];
    while (index < leakString.length) {
      String duplicate = parseString();
      int count = parseInt();

      List<String> prettyPrints = [];
      for (int i = 0; i < count; i++) {
        String data = parseString();
        prettyPrints.add(data);
      }
      result.add(new Leak(duplicate, count, prettyPrints));
    }
    return result;
  }

  int _latestLeakIteration = -1;

  void leakDetected(String duplicate, int count, List<String> prettyPrints) {
    if (_iterationNumber != _latestLeakIteration) {
      print("======================================");
      print("WARNING: Duplicated pretty prints of objects.");
      print("This might be a memory leak!");
      print("");
    }
    _latestLeakIteration = _iterationNumber;
    print("$duplicate ($count)");
    for (String prettyPrint in prettyPrints) {
      print(" => ${prettyPrint}");
    }
    print("");
  }

  void noLeakDetected() {}

  bool shouldDoAnotherIteration(int iterationNumber) {
    return true;
  }
}

class Interest {
  final Uri uri;
  final String className;
  final List<String> fieldNames;
  final bool expectToAlwaysFind;

  Interest(
    this.uri,
    this.className,
    this.fieldNames, {
    this.expectToAlwaysFind = false,
  });
}

class Leak {
  final String duplicate;
  final int count;
  final List<String> prettyPrints;

  Leak(this.duplicate, this.count, this.prettyPrints);
}
