// 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.
// VMOptions=--verbose_debug --enable-isolate-groups --experimental-enable-isolate-groups-jit
//
// Tests breakpoint pausing and resuming with many isolates running and pausing
// simultaneously.

import 'dart:async';
import 'dart:developer';
import 'dart:isolate' as dart_isolate;

import 'package:observatory_2/service_io.dart';
import 'package:test/test.dart';

import 'service_test_common.dart';
import 'test_helper.dart';

const int LINE_A = 23;
const int LINE_B = 35;
const int LINE_C = 41;

foo(args) { // LINE_A
  print('${dart_isolate.Isolate.current.debugName}: $args');
  final sendPort = args[0] as dart_isolate.SendPort;
  final int i = args[1] as int;
  sendPort.send('reply from foo: $i');
}

int nIsolates = -1;

testMain() async {
  final rps = List<dart_isolate.ReceivePort>.generate(
      nIsolates, (i) => dart_isolate.ReceivePort());
  debugger(); // LINE_B
  for (int i = 0; i < nIsolates; i++) {
    await dart_isolate.Isolate.spawn(foo, [rps[i].sendPort, i],
        debugName: "foo$i");
  }
  print(await Future.wait(rps.map((rp) => rp.first)));
  debugger(); // LINE_C
}

final completerAtFoo = List<Completer>.generate(nIsolates, (_) => Completer());
int completerCount = 0;

final tests = <IsolateTest>[
  hasPausedAtStart,
  resumeIsolate,
  hasStoppedAtBreakpoint,
  stoppedAtLine(LINE_B + 1),
  (Isolate isolate) async {
    // Set up a listener to wait for child isolate launch and breakpoint events.
    final stream = await isolate.vm.getEventStream(VM.kDebugStream);
    var subscription;
    subscription = stream.listen((ServiceEvent event) async {
      switch (event.kind) {
        case ServiceEvent.kPauseStart:
          final childIsolate = event.isolate;
          await childIsolate.reload();

          for (Library lib in childIsolate.libraries) {
            await lib.load();
            if (lib.uri
                .endsWith('break_on_function_many_child_isolates_test.dart')) {
              final foo = lib.functions.singleWhere((f) => f.name == 'foo');
              final bpt = await childIsolate.addBreakpointAtEntry(foo);

              expect(bpt is Breakpoint, isTrue);
              break;
            }
          }
          childIsolate.resume();
          break;
        case ServiceEvent.kPauseBreakpoint:
          final name = event.isolate.name;
          if (!name.startsWith('foo')) {
            break;
          }
          final childIsolate = event.isolate;
          final ndx = int.parse(name.substring('foo'.length));
          final stack = await childIsolate.getStack();
          final top = stack['frames'][0];
          final script = await top.location.script.load() as Script;
          expect(script.tokenToLine(top.location.tokenPos), equals(LINE_A));

          childIsolate.resume();
          if ((++completerCount) == nIsolates) {
            subscription.cancel();
          }
          completerAtFoo[ndx].complete();
          break;
      }
    });
  },
  resumeIsolate,
  (Isolate isolate) async {
    await Future.wait(completerAtFoo.map((c) => c.future));
  },
  hasStoppedAtBreakpoint,
  stoppedAtLine(LINE_C + 1),
  resumeIsolate,
];

Future runIsolateBreakpointPauseTest(args, nIsolates_) {
  nIsolates = nIsolates_;
  return runIsolateTests(args, tests,
      testeeConcurrent: testMain, pause_on_start: true);
}

main(args) async {
  await runIsolateBreakpointPauseTest(args, /*nIsolates=*/ 30);
}
