// 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 'dart:io';
import 'dart:isolate';

import 'package:http/http.dart' as http;

void main() async {
  // Start a server to obtain a randomly assigned, free port.
  final mainServer = await HttpServer.bind('::1', 0, shared: true);
  final sharedPort = mainServer.port;

  final workers = List<ServerWorker>.generate(
    4,
    (i) => ServerWorker(i, sharedPort),
  );
  await Future.wait(workers.map((w) => w.start()));
  mainServer.close();

  await Future.delayed(Duration(seconds: 1));
  // spawn client isolate
  final clientisolate = await Isolate.spawn(client, sharedPort);
  // Wait for 20 secs. It used to crash within 10 seconds.
  await Future.delayed(Duration(seconds: 20));

  workers.forEach((w) {
    w.respawn = false;
    w.terminate();
  });
  print('kill client isolates');
  clientisolate.kill();
}

class ServerWorker {
  final int workerid;
  final int port;
  Isolate? _isolate;
  bool respawn = true;

  ServerWorker(this.workerid, this.port);

  Future<void> start() async {
    final onExit = ReceivePort();
    onExit.listen((_) {
      onExit.close();
      // Respawn another isolate
      if (respawn) start();
    });
    final ready = ReceivePort();
    _isolate = await Isolate.spawn(
      _main,
      [workerid, port, ready.sendPort],
      errorsAreFatal: true,
      onExit: onExit.sendPort,
    );
    await ready.first;
    if (workerid == 0) terminate();
  }

  void terminate() {
    Future.delayed(Duration(seconds: 1), () {
      print('terminate ${workerid}');
      _isolate?.kill();
      _isolate = null;
    });
  }

  static _main(List args) async {
    final workerid = args[0] as int;
    final port = args[1] as int;
    final readyPort = args[2] as SendPort;

    final server = await HttpServer.bind('::1', port, shared: true);
    readyPort.send(null);
    server.listen((HttpRequest request) {
      print('from worker ${workerid}');
      final response = request.response;
      response.statusCode = HttpStatus.ok;
      response.write('server worker ${workerid}');
      response.close();
    });
  }
}

Future<String> get(Uri url) async {
  while (true) {
    try {
      await http.get(url);
      return '';
    } catch (err) {}
  }
}

void client(int port) async {
  while (true) {
    final futures = <Future>[];
    final numAtOnce = 16; // enough to keep the server busy
    for (int i = 0; i < numAtOnce; ++i) {
      futures.add(get(Uri.http('localhost:$port', '')).then((_) {}));
    }
    await Future.wait(futures);
  }
}
