// 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.

/// @assertion int maxConnectionsPerHost
/// read / write
/// Get and set the maximum number of live connections, to a single host.
///
/// Increasing this number may lower performance and take up unwanted system
/// resources.
///
/// To disable, set to null.
///
/// Default is null.
/// @description Checks that this property get and set the maximum number of live
/// connections, to a single host
/// @author sgrekhov@unipro.ru

import "dart:io";
import "../../../Utils/expect.dart";

var localhost = InternetAddress.loopbackIPv4.address;

void test(int? maxConnections, int max) {
  asyncStart();
  HttpServer.bind(localhost, 0).then((server) {
    int handled = 0;
    server.listen((request) {
      if (maxConnections != null) {
        Expect.isTrue(server.connectionsInfo().total <= maxConnections);
      }
      request.response.close();
      handled++;
      if (handled == max) {
        asyncEnd();
        server.close();
      }
    });

    var client = new HttpClient();
    client.maxConnectionsPerHost = maxConnections;
    for (int i = 0; i < max; i++) {
      asyncStart();
      client.getUrl(Uri.parse("http://${localhost}:${server.port}"))
          .then((request) => request.close()).then((response) {
        response.listen(null, onDone: () {
          asyncEnd();
        });
      });
    }
  });
}

void main() {
  test(1, 1);
  test(1, 10);
  test(5, 10);
  test(10, 50);
  test(null, 5);
}
