// Copyright (c) 2021, 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 'dart:developer';
import 'package:observatory_2/models.dart' as M;
import 'package:observatory_2/service_io.dart';
import 'package:observatory_2/sample_profile.dart';
import 'package:test/test.dart';
import 'service_test_common.dart';
import 'test_helper.dart';

class Foo {
  Foo() {
    print('Foo');
  }
}

class Bar {
  Bar() {
    print('Bar');
  }
}

void test() {
  debugger();
  // Toggled on for Foo.
  debugger();
  debugger();
  // Traced allocation.
  Foo();
  // Untraced allocation.
  Bar();
  // Toggled on for Bar.
  debugger();
  debugger();
  // Traced allocation.
  Bar();
  debugger();
}

var tests = <IsolateTest>[
  hasStoppedAtBreakpoint,

  // Initial.
  (Isolate isolate) async {
    // Verify initial state of 'Foo'.
    final fooClass = await getClassFromRootLib(isolate, 'Foo');
    expect(fooClass, isNotNull);
    expect(fooClass.name, equals('Foo'));
    print(fooClass.id);
    expect(fooClass.traceAllocations, isFalse);
    await fooClass.setTraceAllocations(true);
    await fooClass.reload();
    expect(fooClass.traceAllocations, true);
  },

  resumeIsolate,
  hasStoppedAtBreakpoint,
  // Extra debugger stop, continue to allow the allocation stubs to be switched
  // over. This is a bug but low priority.
  resumeIsolate,
  hasStoppedAtBreakpoint,

  // Allocation profile.
  (Isolate isolate) async {
    final fooClass = await getClassFromRootLib(isolate, 'Foo');
    await fooClass.reload();
    expect(fooClass.traceAllocations, true);

    final profileResponse = (await isolate.getAllocationTraces()) as ServiceMap;
    expect(profileResponse, isNotNull);
    expect(profileResponse['type'], 'CpuSamples');
    expect(profileResponse['samples'].length, 1);
    expect(profileResponse['samples'][0]['identityHashCode'], isNotNull);
    expect(profileResponse['samples'][0]['identityHashCode'] != 0, true);
    await fooClass.setTraceAllocations(false);
    await fooClass.reload();
    expect(fooClass.traceAllocations, isFalse);

    // Verify the allocation trace for the `Foo()` allocation.
    final cpuProfile = SampleProfile();
    await cpuProfile.load(isolate, profileResponse);
    cpuProfile.buildCodeCallerAndCallees();
    cpuProfile.buildFunctionCallerAndCallees();
    final tree = cpuProfile.loadCodeTree(M.ProfileTreeDirection.exclusive);
    var node = tree.root;
    final expected = [
      'Root',
      '[Unoptimized] test',
      '[Unoptimized] test',
      '[Unoptimized] _ServiceTesteeRunner.run',
    ];
    for (var i = 0; i < expected.length; i++) {
      expect(node.profileCode.code.name, equals(expected[i]));
      // Depth first traversal.
      if (node.children.length == 0) {
        node = null;
      } else {
        node = node.children[0];
      }
      expect(node, isNotNull);
    }
  },
  resumeIsolate,
  hasStoppedAtBreakpoint,
  (Isolate isolate) async {
    // Trace Bar.
    final barClass = await getClassFromRootLib(isolate, 'Bar');
    await barClass.reload();
    expect(barClass.traceAllocations, false);
    await barClass.setTraceAllocations(true);
    await barClass.reload();
    expect(barClass.traceAllocations, true);
  },

  resumeIsolate,
  hasStoppedAtBreakpoint,
  // Extra debugger stop, continue to allow the allocation stubs to be switched
  // over. This is a bug but low priority.
  resumeIsolate,
  hasStoppedAtBreakpoint,

  (Isolate isolate) async {
    // Ensure the allocation of `Bar()` was recorded.
    final profileResponse = (await isolate.getAllocationTraces()) as ServiceMap;
    expect(profileResponse['samples'].length, 2);
  },
];

main(args) async => runIsolateTests(args, tests, testeeConcurrent: test);
