// Copyright (c) 2019, 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: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 pkg/vm_service/test/async_scope_test.dart
//
const LINE_A = 28;
const LINE_B = 35;
const LINE_C = 40;
// AUTOGENERATED END

void foo() {}

Future<void> doAsync(int param1) async {
  final local1 = param1 + 1;
  foo(); // LINE_A
  // ignore: await_only_futures
  await local1;
}

Stream<int> doAsyncStar(int param2) async* {
  final local2 = param2 + 1;
  foo(); // LINE_B
  yield local2;
}

void testeeDo() {
  debugger(); // LINE_C

  doAsync(1).then((_) {
    doAsyncStar(1).listen((_) {});
  });
}

Future<void> checkAsyncVarDescriptors(
  VmService service,
  IsolateRef isolateRef,
) async {
  final isolateId = isolateRef.id!;
  final stack = await service.getStack(isolateId);
  expect(stack.frames!.length, greaterThanOrEqualTo(1));
  final frame = stack.frames![0];
  final vars = frame.vars!.map((v) => v.name).join(' ');
  expect(vars, 'param1 local1'); // no :async_op et al
}

Future checkAsyncStarVarDescriptors(
  VmService service,
  IsolateRef isolateRef,
) async {
  final isolateId = isolateRef.id!;
  final stack = await service.getStack(isolateId);
  expect(stack.frames!.length, greaterThanOrEqualTo(1));
  final frame = stack.frames![0];
  final vars = frame.vars!.map((v) => v.name).join(' ');
  expect(vars, 'param2 local2'); // no :async_op et al
}

final tests = <IsolateTest>[
  hasStoppedAtBreakpoint,
  stoppedAtLine(LINE_C),
  setBreakpointAtLine(LINE_A),
  setBreakpointAtLine(LINE_B),
  resumeIsolate,
  hasStoppedAtBreakpoint,
  stoppedAtLine(LINE_A),
  checkAsyncVarDescriptors,
  resumeIsolate,
  hasStoppedAtBreakpoint,
  stoppedAtLine(LINE_B),
  checkAsyncStarVarDescriptors,
  resumeIsolate,
];

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