// Copyright (c) 2023, 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

import 'dart:async';

import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';

import 'common/service_test_common.dart';
import 'common/test_helper.dart';

// AUTOGENERATED START
//
// Update these constants by running:
//
// dart pkg/vm_service/test/update_line_numbers.dart <test.dart>
//
const LINE_A = 31;
const LINE_B = 34;
const LINE_C = 41;
const LINE_D = 48;
// AUTOGENERATED END

// DO NOT REORDER BEYOND THIS POINT
bool testing = false;
void printSync() {
  print('sync');
  if (testing) {
    // LINE_A
    // We'll never reach this code, but setting a breakpoint here will result in
    // the breakpoint being resolved below at line LINE_C.
    print('unreachable'); // LINE_B
  }
}

Iterable<void> printSyncStar() sync* {
  // We'll end up resolving breakpoint 1 to this location instead of at LINE_A
  // if #46419 regresses.
  print('sync*'); // LINE_C
}

void testeeDo() {
  printSync();
  final iterator = printSyncStar();

  print('middle'); // LINE_D

  iterator.toList();
}
// END DO NOT REORDER SECTION

late Breakpoint bp1;
late Breakpoint bp2;

final tests = <IsolateTest>[
  hasPausedAtStart,
  (VmService service, IsolateRef isolateRef) async {
    final isolateId = isolateRef.id!;
    final isolate = await service.getIsolate(isolateId);
    final rootLib = await service.getObject(
      isolateId,
      isolate.rootLib!.id!,
    ) as Library;
    final scriptId = rootLib.scripts!.first.id!;

    bp1 = await service.addBreakpoint(isolateId, scriptId, LINE_B);
    print('BP1 - $bp1');
    bp2 = await service.addBreakpoint(isolateId, scriptId, LINE_D);
    print('BP2 - $bp2');

    final done = Completer<void>();
    late final StreamSubscription sub;
    sub = service.onDebugEvent.listen((event) async {
      if (event.kind == EventKind.kPauseBreakpoint) {
        expect(event.pauseBreakpoints!.length, 1);
        final bp = event.pauseBreakpoints!.first;
        print('Hit $bp');
        expect(bp, bp2);
        await sub.cancel();
        await service.streamCancel(EventStreams.kDebug);
        await service.resume(isolateId);
        done.complete();
      }
    });
    await service.streamListen(EventStreams.kDebug);
    await service.resume(isolateId);
    await done.future;
  }
];

void main([args = const <String>[]]) => runIsolateTests(
      args,
      tests,
      'regress_46419_test.dart',
      testeeConcurrent: testeeDo,
      pauseOnStart: true,
    );
