// 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:async';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/test_helper.dart';

printSync() {
  print('sync'); // Line 11
}

printAsync() async {
  await null;
  print('async'); // Line 16
}

printAsyncStar() async* {
  await null;
  print('async*'); // Line 21
}

printSyncStar() sync* {
  print('sync*'); // Line 25
}

var testerReady = false;
testeeDo() {
  // We block here rather than allowing the isolate to enter the
  // paused-on-exit state before the tester gets a chance to set
  // the breakpoints because we need the event loop to remain
  // operational for the async bodies to run.
  print('testee waiting');
  while (!testerReady) {}

  printSync();
  final future = printAsync();
  final stream = printAsyncStar();
  final iterator = printSyncStar();

  print('middle'); // Line 42

  future.then((v) => print(v));
  stream.toList();
  iterator.toList();
}

Future testAsync(VmService service, IsolateRef isolateRef) async {
  final isolate = await service.getIsolate(isolateRef.id);
  final lib = await service.getObject(isolate.id, isolate.rootLib.id);
  final script = lib.scripts[0];

  final bp1 = await service.addBreakpoint(isolate.id, script.id, 11);
  expect(bp1, isNotNull);
  expect(bp1 is Breakpoint, isTrue);

  final bp2 = await service.addBreakpoint(isolate.id, script.id, 16);
  expect(bp2, isNotNull);
  expect(bp2 is Breakpoint, isTrue);

  final bp3 = await service.addBreakpoint(isolate.id, script.id, 21);
  expect(bp3, isNotNull);
  expect(bp3 is Breakpoint, isTrue);

  final bp4 = await service.addBreakpoint(isolate.id, script.id, 25);
  expect(bp4, isNotNull);
  expect(bp4 is Breakpoint, isTrue);

  final bp5 = await service.addBreakpoint(isolate.id, script.id, 42);
  expect(bp5, isNotNull);
  expect(bp5 is Breakpoint, isTrue);

  final hits = <Breakpoint>[];
  await service.streamListen(EventStreams.kDebug);

  // ignore: unawaited_futures
  service
      .evaluate(isolate.id, lib.id, 'testerReady = true')
      .then((result) async {
    result = await service.getObject(isolate.id, result.id);
    print(result);
    expect((result as Instance).valueAsString, equals('true'));
  });

  final stream = service.onDebugEvent;
  await for (Event event in stream) {
    if (event.kind == EventKind.kPauseBreakpoint) {
      assert(event.pauseBreakpoints.isNotEmpty);
      final bp = event.pauseBreakpoints.first;
      hits.add(bp);
      await service.resume(isolate.id);

      if (hits.length == 5) break;
    }
  }

  expect(hits, equals([bp1, bp5, bp4, bp2, bp3]));
}

final tests = <IsolateTest>[testAsync];

main([args = const <String>[]]) =>
    runIsolateTests(args, tests, testeeConcurrent: testeeDo);
