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

// @dart = 2.9

import "vm_service_helper.dart" as vmService;

class VMServiceHeapHelperSpecificExactLeakFinder
    extends vmService.LaunchingVMServiceHelper {
  final Set _interestsClassNames = {};
  final Map<Uri, Map<String, List<String>>> _interests =
      new Map<Uri, Map<String, List<String>>>();
  final Map<Uri, Map<String, List<String>>> _prettyPrints =
      new Map<Uri, Map<String, List<String>>>();
  final bool throwOnPossibleLeak;

  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) {
      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);
    }
  }

  void pause() async {
    await serviceClient.pause(_isolateRef.id);
  }

  vmService.VM _vm;
  vmService.IsolateRef _isolateRef;
  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;
  }

  @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;
      await waitUntilPaused(_isolateRef.id);
      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 = [];
      for (vmService.ClassHeapStats member in allocationProfile.members) {
        if (_interestsClassNames.contains(member.classRef.name)) {
          vmService.Class c =
              await serviceClient.getObject(_isolateRef.id, member.classRef.id);
          String uriString = c.location?.script?.uri;
          if (uriString == null) continue;
          Uri uri = Uri.parse(uriString);
          Map<String, List<String>> uriInterest = _interests[uri];
          if (uriInterest == null) continue;
          List<String> fieldsForClass = uriInterest[c.name];
          if (fieldsForClass == null) continue;

          List<String> fieldsForClassPrettyPrint = fieldsForClass;

          uriInterest = _prettyPrints[uri];
          if (uriInterest != null) {
            if (uriInterest[c.name] != null) {
              fieldsForClassPrettyPrint = uriInterest[c.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();
      }

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

      await serviceClient.resume(_isolateRef.id);
      _iterationNumber++;
    }
  }

  Future<List<Leak>> _findLeaks(
      vmService.IsolateRef isolateRef,
      vmService.ClassRef classRef,
      List<String> fieldsForClass,
      List<String> fieldsForClassPrettyPrint) async {
    // Use undocumented (/ private?) method to get all instances of this class.
    vmService.InstanceRef instancesAsList = await serviceClient.callMethod(
      "_getInstancesAsArray",
      isolateId: isolateRef.id,
      args: {
        "objectId": classRef.id,
        "includeSubclasses": false,
        "includeImplementors": 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;
              })
        """,
    );
    // 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
        """,
    );
    vmService.Instance duplicatesLength =
        await serviceClient.getObject(isolateRef.id, duplicatesLengthRef.id);
    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(":")
          """,
      );
      if (duplicatesDataRef is! vmService.InstanceRef) {
        if (duplicatesDataRef is vmService.ErrorRef) {
          vmService.Error error = await serviceClient.getObject(
              isolateRef.id, duplicatesDataRef.id);
          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);
      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;

  Interest(this.uri, this.className, this.fieldNames);
}

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

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