// Copyright (c) 2013, 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.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

import "package:expect/expect.dart";
import "dart:async";
import "dart:io";
import "dart:typed_data";


void testClientAndServerCloseNoListen(int connections) {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    int closed = 0;
    server.listen((request) {
      request.response.close();
      request.response.done.then((_) {
        closed++;
        if (closed == connections) {
          Expect.equals(0, server.connectionsInfo().active);
          Expect.equals(server.connectionsInfo().total,
                        server.connectionsInfo().idle);
          server.close();
        }
      });
    });
    var client = new HttpClient();
    for (int i = 0; i < connections; i++) {
      client.get("127.0.0.1", server.port, "/")
          .then((request) => request.close())
          .then((response) {
          });
    }
  });
}


void testClientCloseServerListen(int connections) {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    int closed = 0;
    void check() {
      closed++;
      if (closed == connections * 2) {
        Expect.equals(0, server.connectionsInfo().active);
        Expect.equals(server.connectionsInfo().total,
                      server.connectionsInfo().idle);
        server.close();
      }
    }
    server.listen((request) {
      request.listen(
          (_) {},
          onDone: () {
            request.response.close();
            request.response.done.then((_) => check());
          });
    });
    var client = new HttpClient();
    for (int i = 0; i < connections; i++) {
      client.get("127.0.0.1", server.port, "/")
          .then((request) => request.close())
          .then((response) => check());
    }
  });
}


void testClientCloseSendingResponse(int connections) {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    int closed = 0;
    void check() {
      closed++;
      // Wait for both server and client to see the connections as closed.
      if (closed == connections * 2) {
        Expect.equals(0, server.connectionsInfo().active);
        Expect.equals(server.connectionsInfo().total,
                      server.connectionsInfo().idle);
        server.close();
      }
    }
    server.listen((request) {
      var timer = new Timer.periodic(const Duration(milliseconds: 20), (_) {
        request.response.add(new Uint8List(16 * 1024));
      });
      request.response.done
          .catchError((_) {})
          .whenComplete(() {
            check();
            timer.cancel();
          });
    });
    var client = new HttpClient();
    for (int i = 0; i < connections; i++) {
      client.get("127.0.0.1", server.port, "/")
          .then((request) => request.close())
          .then((response) {
            // Ensure we don't accept the response until we have send the entire
            // request.
            var subscription = response.listen((_) {});
            new Timer(const Duration(milliseconds: 200), () {
              subscription.cancel();
              check();
            });
          });
    }
  });
}


void testClientCloseWhileSendingRequest(int connections) {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    int errors = 0;
    server.listen((request) {
      request.listen((_) {}, onError: (e) { errors++; });
    });
    var client = new HttpClient();
    for (int i = 0; i < connections; i++) {
      client.post("127.0.0.1", server.port, "/")
          .then((request) {
            request.contentLength = 110;
            request.write("0123456789");
            return request.close();
          })
          .catchError((_) {});
    }
    new Timer.periodic(const Duration(milliseconds: 100), (t) {
      if (errors == connections && server.connectionsInfo().total == 0) {
        t.cancel();
        server.close();
      }
    });
  });
}


void main() {
  testClientAndServerCloseNoListen(10);
  testClientCloseServerListen(10);
  testClientCloseSendingResponse(10);
  testClientCloseWhileSendingRequest(10);
}

