// Copyright (c) 2014, 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 'package:observatory/models.dart' as M;
import 'package:observatory/object_graph.dart';
import 'package:observatory/service_io.dart';
import 'package:test/test.dart';
import 'test_helper.dart';

class Foo {
  // Make sure these fields are not removed by the tree shaker.
  @pragma("vm:entry-point")
  dynamic left;
  @pragma("vm:entry-point")
  dynamic right;
}

late Foo r;

late List lst;

void script() {
  // Create 3 instances of Foo, with out-degrees
  // 0 (for b), 1 (for a), and 2 (for staticFoo).
  r = new Foo();
  var a = new Foo();
  var b = new Foo();
  r.left = a;
  r.right = b;
  a.left = b;

  lst = new List<dynamic>.filled(2, null);
  lst[0] = lst; // Self-loop.
  // Larger than any other fixed-size list in a fresh heap.
  lst[1] = new List<dynamic>.filled(1234569, null);
}

var tests = <IsolateTest>[
  (Isolate isolate) async {
    var graph = await isolate.fetchHeapSnapshot().done;

    Iterable<SnapshotObject> foos =
        graph.objects.where((SnapshotObject obj) => obj.klass.name == "Foo");
    expect(foos.length, equals(3));

    SnapshotObject bVertex = foos.singleWhere((SnapshotObject obj) {
      List<SnapshotObject> successors = obj.successors.toList();
      return successors[0].klass.name == "Null" &&
          successors[1].klass.name == "Null";
    });
    SnapshotObject aVertex = foos.singleWhere((SnapshotObject obj) {
      List<SnapshotObject> successors = obj.successors.toList();
      return successors[0].klass.name == "Foo" &&
          successors[1].klass.name == "Null";
    });
    SnapshotObject rVertex = foos.singleWhere((SnapshotObject obj) {
      List<SnapshotObject> successors = obj.successors.toList();
      return successors[0].klass.name == "Foo" &&
          successors[1].klass.name == "Foo";
    });

    // TODO(koda): Check actual byte sizes.

    expect(aVertex.retainedSize, equals(aVertex.shallowSize));
    expect(bVertex.retainedSize, equals(bVertex.shallowSize));
    expect(
        rVertex.retainedSize,
        equals(
            aVertex.shallowSize + bVertex.shallowSize + rVertex.shallowSize));

    List<SnapshotObject> lists = new List.from(
        graph.objects.where((SnapshotObject obj) => obj.klass.name == '_List'));
    expect(lists.length >= 2, isTrue);
    // Order by decreasing retained size.
    lists.sort((u, v) => v.retainedSize - u.retainedSize);
    SnapshotObject first = lists[0];
    expect(first.successors.length, greaterThanOrEqualTo(2));
    SnapshotObject second = lists[1];
    expect(second.successors.length, greaterThanOrEqualTo(1234569));
    // Check that the short list retains more than the long list inside.
    // and specifically, that it retains exactly itself + the long one.
    expect(first.retainedSize, equals(first.shallowSize + second.shallowSize));

    // Verify sizes of classes are the appropriates sums of their instances.
    // This also verifies that the class instance iterators are visiting the
    // correct set of objects (e.g., not including dead objects).
    for (SnapshotClass klass in graph.classes) {
      int shallowSum = 0;
      int internalSum = 0;
      int externalSum = 0;
      for (SnapshotObject instance in klass.instances) {
        if (instance == graph.root) {
          // The root may have 0 self size.
          expect(instance.internalSize, greaterThanOrEqualTo(0));
          expect(instance.externalSize, greaterThanOrEqualTo(0));
          expect(instance.shallowSize, greaterThanOrEqualTo(0));
        } else {
          // All other objects are heap objects with positive size.
          expect(instance.internalSize, greaterThan(0));
          expect(instance.externalSize, greaterThanOrEqualTo(0));
          expect(instance.shallowSize, greaterThan(0));
        }
        expect(instance.retainedSize, greaterThan(0));
        expect(instance.shallowSize,
            equals(instance.internalSize + instance.externalSize));
        shallowSum += instance.shallowSize;
        internalSum += instance.internalSize;
        externalSum += instance.externalSize;
      }
      expect(shallowSum, equals(klass.shallowSize));
      expect(internalSum, equals(klass.internalSize));
      expect(externalSum, equals(klass.externalSize));
      expect(
          klass.shallowSize, equals(klass.internalSize + klass.externalSize));
    }

    // Verify sizes of the overall graph are the appropriates sums of all
    // instances. This also verifies that the all instances iterator is visiting
    // the correct set of objects (e.g., not including dead objects).
    int shallowSum = 0;
    int internalSum = 0;
    int externalSum = 0;
    for (SnapshotObject instance in graph.objects) {
      if (instance == graph.root) {
        // The root may have 0 self size.
        expect(instance.internalSize, greaterThanOrEqualTo(0));
        expect(instance.externalSize, greaterThanOrEqualTo(0));
        expect(instance.shallowSize, greaterThanOrEqualTo(0));
      } else {
        // All other objects are heap objects with positive size.
        expect(instance.internalSize, greaterThan(0));
        expect(instance.externalSize, greaterThanOrEqualTo(0));
        expect(instance.shallowSize, greaterThan(0));
      }
      expect(instance.retainedSize, greaterThan(0));
      expect(instance.shallowSize,
          equals(instance.internalSize + instance.externalSize));
      shallowSum += instance.shallowSize;
      internalSum += instance.internalSize;
      externalSum += instance.externalSize;
    }
    expect(shallowSum, equals(graph.size));
    expect(internalSum, equals(graph.internalSize));
    expect(externalSum, equals(graph.externalSize));
    expect(graph.size, equals(graph.internalSize + graph.externalSize));
  },
];

main(args) => runIsolateTests(args, tests, testeeBefore: script);
