// Copyright (c) 2014, 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 http_multi_server.test;

import 'dart:async';
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:http_multi_server/http_multi_server.dart';
import 'package:http_multi_server/src/utils.dart';
import 'package:unittest/unittest.dart';

void main() {
  group("with multiple HttpServers", () {
    var multiServer;
    var subServer1;
    var subServer2;
    var subServer3;
    setUp(() {
      return Future.wait([
        HttpServer.bind("127.0.0.1", 0).then((server) => subServer1 = server),
        HttpServer.bind("127.0.0.1", 0).then((server) => subServer2 = server),
        HttpServer.bind("127.0.0.1", 0).then((server) => subServer3 = server)
      ]).then((servers) => multiServer = new HttpMultiServer(servers));
    });

    tearDown(() => multiServer.close());

    test("listen listens to all servers", () {
      multiServer.listen((request) {
        request.response.write("got request");
        request.response.close();
      });

      expect(_read(subServer1), completion(equals("got request")));
      expect(_read(subServer2), completion(equals("got request")));
      expect(_read(subServer3), completion(equals("got request")));
    });

    test("serverHeader= sets the value for all servers", () {
      multiServer.serverHeader = "http_multi_server test";

      multiServer.listen((request) {
        request.response.write("got request");
        request.response.close();
      });

      expect(_get(subServer1).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);

      expect(_get(subServer2).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);

      expect(_get(subServer3).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);
    });

    test("headers.set sets the value for all servers", () {
      multiServer.defaultResponseHeaders.set(
          "server", "http_multi_server test");

      multiServer.listen((request) {
        request.response.write("got request");
        request.response.close();
      });

      expect(_get(subServer1).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);

      expect(_get(subServer2).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);

      expect(_get(subServer3).then((response) {
        expect(response.headers['server'], equals("http_multi_server test"));
      }), completes);
    });

    test("connectionsInfo sums the values for all servers", () {
      var pendingRequests = 0;
      var awaitingResponseCompleter = new Completer();
      var sendResponseCompleter = new Completer();
      multiServer.listen((request) {
        sendResponseCompleter.future.then((_) {
          request.response.write("got request");
          request.response.close();
        });

        pendingRequests++;
        if (pendingRequests == 2) awaitingResponseCompleter.complete();
      });

      // Queue up some requests, then wait on [awaitingResponseCompleter] to
      // make sure they're in-flight before we check [connectionsInfo].
      expect(_get(subServer1), completes);
      expect(_get(subServer2), completes);

      return awaitingResponseCompleter.future.then((_) {
        var info = multiServer.connectionsInfo();
        expect(info.total, equals(2));
        expect(info.active, equals(2));
        expect(info.idle, equals(0));
        expect(info.closing, equals(0));

        sendResponseCompleter.complete();
      });
    });
  });

  group("HttpMultiServer.loopback", () {
    var server;
    setUp(() {
      return HttpMultiServer.loopback(0).then((server_) => server = server_);
    });

    tearDown(() => server.close());

    test("listens on all localhost interfaces", () {
      server.listen((request) {
        request.response.write("got request");
        request.response.close();
      });

      expect(http.read("http://127.0.0.1:${server.port}/"),
          completion(equals("got request")));

      return supportsIpV6.then((supportsIpV6) {
        if (!supportsIpV6) return;
        expect(http.read("http://[::1]:${server.port}/"),
            completion(equals("got request")));
      });
    });
  });
}

/// Makes a GET request to the root of [server] and returns the response.
Future<http.Response> _get(HttpServer server) => http.get(_urlFor(server));

/// Makes a GET request to the root of [server] and returns the response body.
Future<String> _read(HttpServer server) => http.read(_urlFor(server));

/// Returns the URL for the root of [server].
String _urlFor(HttpServer server) =>
    "http://${server.address.host}:${server.port}/";
