// 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/heap_snapshot.dart';
import 'package:observatory/models.dart' as M;
import 'package:observatory/object_graph.dart';
import 'package:observatory/service_io.dart';
import 'package:unittest/unittest.dart';
import 'test_helper.dart';

class Foo {
  dynamic left;
  dynamic right;
}

Foo r;

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(2);
  lst[0] = lst; // Self-loop.
  // Larger than any other fixed-size list in a fresh heap.
  lst[1] = new List(123456);
}

int fooId;

var tests = <IsolateTest>[
  (Isolate isolate) async {
    Library lib = await isolate.rootLibrary.load();
    expect(lib.classes.length, equals(1));
    Class fooClass = lib.classes.first;
    fooId = fooClass.vmCid;

    RawHeapSnapshot raw =
        await isolate.fetchHeapSnapshot(M.HeapSnapshotRoots.user, false).last;
    HeapSnapshot snapshot = new HeapSnapshot();
    await snapshot.loadProgress(isolate, raw).last;
    ObjectGraph graph = snapshot.graph;

    expect(fooId, isNotNull);
    Iterable<ObjectVertex> foos =
        graph.vertices.where((ObjectVertex obj) => obj.vmCid == fooId);
    expect(foos.length, equals(3));
    expect(foos.where((obj) => obj.successors.length == 0).length, equals(1));
    expect(foos.where((obj) => obj.successors.length == 1).length, equals(1));
    expect(foos.where((obj) => obj.successors.length == 2).length, equals(1));

    ObjectVertex bVertex =
        foos.where((ObjectVertex obj) => obj.successors.length == 0).first;
    ObjectVertex aVertex =
        foos.where((ObjectVertex obj) => obj.successors.length == 1).first;
    ObjectVertex rVertex =
        foos.where((ObjectVertex obj) => obj.successors.length == 2).first;

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

    Library corelib =
        isolate.libraries.singleWhere((lib) => lib.uri == 'dart:core');
    await corelib.load();
    Class _List =
        corelib.classes.singleWhere((cls) => cls.vmName.startsWith('_List'));
    int kArrayCid = _List.vmCid;
    // startsWith to ignore the private mangling
    List<ObjectVertex> lists = new List.from(
        graph.vertices.where((ObjectVertex obj) => obj.vmCid == kArrayCid));
    expect(lists.length >= 2, isTrue);
    // Order by decreasing retained size.
    lists.sort((u, v) => v.retainedSize - u.retainedSize);
    ObjectVertex first = lists[0];
    ObjectVertex second = lists[1];
    // Check that the short list retains more than the long list inside.
    expect(first.successors.length, equals(2 + second.successors.length));
    // ... and specifically, that it retains exactly itself + the long one.
    expect(first.retainedSize, equals(first.shallowSize + second.shallowSize));
  },
];

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