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

import "dart:isolate" as dart;

void isolate(dart.SendPort port) {
  dart.RawReceivePort receive = new dart.RawReceivePort((_) {
    debugger();
    throw new Exception();
  });
  port.send(receive.sendPort);
}

void test() {
  dart.RawReceivePort receive = new dart.RawReceivePort((port) {
    debugger();
    port.send(null);
    debugger();
    port.send(null);
    debugger();
  });
  dart.Isolate.spawn(isolate, receive.sendPort);
}

var tests = <IsolateTest>[
  hasPausedAtStart,
  (Isolate isolate) async {
    int step = 0;
    var completer = new Completer();
    var sub;
    final Isolate firstIsolate = isolate;
    print("First isolate is: ${firstIsolate.id}");
    Isolate secondIsolate;
    sub = await isolate.vm.listenEventStream(VM.kDebugStream, (ServiceEvent c) {
      print("Event ${c.kind} on ${c.isolate.id}");
      switch (step) {
        case 0:
          expect(c.kind, equals(ServiceEvent.kResume),
              reason: "First isolate should resume");
          expect(c.isolate.id, equals(firstIsolate.id),
              reason: "First isolate should resume");
          break;
        case 1:
          expect(c.kind, equals(ServiceEvent.kPauseStart),
              reason: "Second isolate should pause on start");
          expect(c.isolate.id, equals(isolate.vm.isolates[1].id),
              reason: "Second isolate should pause on start");
          secondIsolate = c.isolate;
          print("Second isolate is: ${secondIsolate.id}");
          print("Resuming second isolate");
          secondIsolate.resume();
          break;
        case 2:
          expect(c.kind, equals(ServiceEvent.kResume),
              reason: "Second isolate should resume");
          expect(c.isolate.id, equals(secondIsolate.id),
              reason: "Second isolate should resume");
          break;
        case 3:
          expect(c.kind, equals(ServiceEvent.kPauseBreakpoint),
              reason: "First isolate should stop at debugger()");
          expect(c.isolate.id, equals(firstIsolate.id),
              reason: "First isolate should stop at debugger()");
          print("Resuming first isolate");
          firstIsolate.resume();
          break;
        case 4:
          expect(c.kind, equals(ServiceEvent.kResume),
              reason: "First isolate should resume (1)");
          expect(c.isolate.id, equals(firstIsolate.id),
              reason: "First isolate should resume (1)");
          break;
        case 5:
          expect(c.kind, equals(ServiceEvent.kPauseBreakpoint),
              reason: "First & Second isolate should stop at debugger()");
          break;
        case 6:
          expect(c.kind, equals(ServiceEvent.kPauseBreakpoint),
              reason: "First & Second isolate should stop at debugger()");
          print("Resuming second isolate");
          secondIsolate.resume();
          break;
        case 7:
          expect(c.kind, equals(ServiceEvent.kResume),
              reason: "Second isolate should resume before the exception");
          expect(c.isolate.id, equals(secondIsolate.id),
              reason: "Second isolate should resume before the exception");
          break;
        case 8:
          expect(c.kind, equals(ServiceEvent.kPauseExit),
              reason: "Second isolate should exit at the exception");
          expect(c.isolate.id, equals(secondIsolate.id),
              reason: "Second isolate should exit at the exception");
          print("Resuming first isolate");
          firstIsolate.resume();
          break;
        case 9:
          expect(c.kind, equals(ServiceEvent.kResume),
              reason: "First isolate should resume after the exception");
          expect(c.isolate.id, equals(firstIsolate.id),
              reason: "First isolate should resume after the exception");
          break;
        case 10:
          expect(c.isolate.id, equals(firstIsolate.id),
              reason: "First "
                  "isolate should stop at debugger() after exception.\n"
                  "Probably the second resumed even though it was not expect "
                  "to do it.");
          expect(c.kind, equals(ServiceEvent.kPauseBreakpoint),
              reason: "First isolate should stop at debugger() after "
                  "exception.");
          completer.complete();
          break;
        default:
          fail("Shouldn't get here, the second isolate resumed even though it "
              "was not expect to do it");
          break;
      }
      step++;
    });
    print("Resuming first isolate");
    firstIsolate.resume();
    await completer.future;
    // We wait 1 second to account for delays in the service protocol.
    // A late message can still arrive.
    await new Future.delayed(const Duration(seconds: 1));
    // No fails, tear down the stream.
    sub.cancel();
  }
];

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