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

library isolate.example.http_server;

import "dart:async";
import "dart:io";
import "dart:isolate";

import "package:isolate/isolate_runner.dart";
import "package:isolate/ports.dart";
import "package:isolate/runner.dart";

Future<Future<Object> Function()> runHttpServer(
    Runner runner, int port, HttpListener listener) async {
  SendPort stopPort = await runner.run(_startHttpServer, [port, listener]);

  return () => _sendStop(stopPort);
}

Future _sendStop(SendPort stopPort) => singleResponseFuture(stopPort.send);

Future<SendPort> _startHttpServer(List args) async {
  int port = args[0];
  HttpListener listener = args[1];

  var server =
      await HttpServer.bind(InternetAddress.anyIPv6, port, shared: true);
  await listener.start(server);

  return singleCallbackPort((SendPort resultPort) {
    sendFutureResult(new Future.sync(listener.stop), resultPort);
  });
}

/// An [HttpRequest] handler setup. Gets called when with the server, and
/// is told when to stop listening.
///
/// These callbacks allow the listener to set up handlers for HTTP requests.
/// The object should be sendable to an equivalent isolate.
abstract class HttpListener {
  Future start(HttpServer server);
  Future stop();
}

/// An [HttpListener] that sets itself up as an echo server.
///
/// Returns the message content plus an ID describing the isolate that
/// handled the request.
class EchoHttpListener implements HttpListener {
  static const _delay = const Duration(seconds: 2);
  static final _id = Isolate.current.hashCode;
  final SendPort _counter;

  StreamSubscription _subscription;

  EchoHttpListener(this._counter);

  Future start(HttpServer server) async {
    print("Starting isolate $_id");
    _subscription = server.listen((HttpRequest request) async {
      await request.response.addStream(request);
      print("Request to $hashCode");
      request.response.write("#$_id\n");
      var watch = new Stopwatch()..start();
      while (watch.elapsed < _delay);
      print("Response from $_id");
      await request.response.close();
      _counter.send(null);
    });
  }

  Future stop() async {
    print("Stopping isolate $_id");
    await _subscription.cancel();
    _subscription = null;
  }
}

main(List<String> args) async {
  int port = 0;
  if (args.length > 0) {
    port = int.parse(args[0]);
  }

  var counter = new ReceivePort();
  HttpListener listener = new EchoHttpListener(counter.sendPort);

  // Used to ensure the requested port is available or to find an available
  // port if `0` is provided.
  ServerSocket socket =
      await ServerSocket.bind(InternetAddress.anyIPv6, port, shared: true);

  port = socket.port;
  var isolates =
      await Future.wait(new Iterable.generate(5, (_) => IsolateRunner.spawn()),
          cleanUp: (isolate) {
    isolate.close();
  });

  List<Future<Object> Function()> stoppers =
      await Future.wait(isolates.map((IsolateRunner isolate) {
    return runHttpServer(isolate, socket.port, listener);
  }), cleanUp: (shutdownServer) {
    shutdownServer();
  });

  await socket.close();
  int count = 25;

  print("Server listening on port $port for $count requests");
  print("Test with:");
  print("  ab -l -c10 -n $count http://localhost:$port/");
  print("where 'ab' is ApacheBench from, e.g., apache2_tools.");

  await for (var _ in counter) {
    count--;
    if (count == 0) {
      print("Shutting down");
      for (var stopper in stoppers) {
        await stopper();
      }
      counter.close();
    }
  }
  print("Finished");
}
