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

import "dart:async";
import "dart:typed_data";
import "dart:io";

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

void testDefaultResponseHeaders() {
  checkDefaultHeaders(headers) {
    Expect.listEquals(
        headers[HttpHeaders.contentTypeHeader], ['text/plain; charset=utf-8']);
    Expect.listEquals(headers['X-Frame-Options'], ['SAMEORIGIN']);
    Expect.listEquals(headers['X-Content-Type-Options'], ['nosniff']);
    Expect.listEquals(headers['X-XSS-Protection'], ['1; mode=block']);
  }

  checkDefaultHeadersClear(headers) {
    Expect.isNull(headers[HttpHeaders.contentTypeHeader]);
    Expect.isNull(headers['X-Frame-Options']);
    Expect.isNull(headers['X-Content-Type-Options']);
    Expect.isNull(headers['X-XSS-Protection']);
  }

  checkDefaultHeadersClearAB(headers) {
    Expect.isNull(headers[HttpHeaders.contentTypeHeader]);
    Expect.isNull(headers['X-Frame-Options']);
    Expect.isNull(headers['X-Content-Type-Options']);
    Expect.isNull(headers['X-XSS-Protection']);
    Expect.listEquals(headers['a'], ['b']);
  }

  test(bool clearHeaders, Map defaultHeaders, Function checker) {
    HttpServer.bind("127.0.0.1", 0).then((server) {
      if (clearHeaders) server.defaultResponseHeaders.clear();
      if (defaultHeaders != null) {
        defaultHeaders.forEach(
            (name, value) => server.defaultResponseHeaders.add(name, value));
      }
      checker(server.defaultResponseHeaders);
      server.listen((request) {
        request.response.close();
      });

      HttpClient client = new HttpClient();
      client
          .get("127.0.0.1", server.port, "/")
          .then((request) => request.close())
          .then((response) {
        checker(response.headers);
        server.close();
        client.close();
      });
    });
  }

  test(false, null, checkDefaultHeaders);
  test(true, null, checkDefaultHeadersClear);
  test(true, {'a': 'b'}, checkDefaultHeadersClearAB);
}

void testDefaultResponseHeadersContentType() {
  test(bool clearHeaders, String requestBody, List<int> responseBody) {
    HttpServer.bind("127.0.0.1", 0).then((server) {
      if (clearHeaders) server.defaultResponseHeaders.clear();
      server.listen((request) {
        request.response.write(requestBody);
        request.response.close();
      });

      HttpClient client = new HttpClient();
      client
          .get("127.0.0.1", server.port, "/")
          .then((request) => request.close())
          .then((response) {
        response.fold([], (a, b) => a..addAll(b)).then((body) {
          Expect.listEquals(body, responseBody);
        }).whenComplete(() {
          server.close();
          client.close();
        });
      });
    });
  }

  test(false, 'æøå', [195, 166, 195, 184, 195, 165]);
  test(true, 'æøå', [230, 248, 229]);
}

void testListenOn() {
  ServerSocket socket;
  HttpServer server;

  void test(void onDone()) {
    Expect.equals(socket.port, server.port);

    HttpClient client = new HttpClient();
    client.get("127.0.0.1", socket.port, "/").then((request) {
      return request.close();
    }).then((response) {
      response.listen((_) {}, onDone: () {
        client.close();
        onDone();
      });
    }).catchError((e, trace) {
      String msg = "Unexpected error in Http Client: $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    });
  }

  // Test two connection after each other.
  asyncStart();
  ServerSocket.bind("127.0.0.1", 0).then((s) {
    socket = s;
    server = new HttpServer.listenOn(socket);
    Expect.equals(server.address.address, '127.0.0.1');
    Expect.equals(server.address.host, '127.0.0.1');
    server.listen((HttpRequest request) {
      request.listen((_) {}, onDone: () => request.response.close());
    });

    test(() {
      test(() {
        server.close();
        Expect.throws(() => server.port);
        Expect.throws(() => server.address);
        socket.close();
        asyncEnd();
      });
    });
  });
}

void testHttpServerZone() {
  asyncStart();
  Expect.equals(Zone.root, Zone.current);
  runZoned(() {
    Expect.notEquals(Zone.root, Zone.current);
    HttpServer.bind("127.0.0.1", 0).then((server) {
      Expect.notEquals(Zone.root, Zone.current);
      server.listen((request) {
        Expect.notEquals(Zone.root, Zone.current);
        request.response.close();
        server.close();
      });
      new HttpClient()
          .get("127.0.0.1", server.port, '/')
          .then((request) => request.close())
          .then((response) => response.drain())
          .then((_) => asyncEnd());
    });
  });
}

void testHttpServerZoneError() {
  asyncStart();
  Expect.equals(Zone.root, Zone.current);
  runZonedGuarded(() {
    Expect.notEquals(Zone.root, Zone.current);
    HttpServer.bind("127.0.0.1", 0).then((server) {
      Expect.notEquals(Zone.root, Zone.current);
      server.listen((request) {
        Expect.notEquals(Zone.root, Zone.current);
        request.listen((_) {}, onError: (error) {
          Expect.notEquals(Zone.root, Zone.current);
          server.close();
          throw error;
        });
      });
      Socket.connect("127.0.0.1", server.port).then((socket) {
        socket.write('GET / HTTP/1.1\r\nContent-Length: 100\r\n\r\n');
        socket.write('some body');
        socket.close();
        socket.listen(null);
      });
    });
  }, (e, s) {
    asyncEnd();
  });
}

void testHttpServerClientClose() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    runZonedGuarded(() {
      server.listen((request) {
        request.response.bufferOutput = false;
        request.response.add(new Uint8List(64 * 1024));
        new Timer(const Duration(milliseconds: 100), () {
          request.response.close().then((_) {
            server.close();
          });
        });
      });
    }, (e, s) {
      Expect.fail("Unexpected error: $e(${e.hashCode})\n$s");
    });
    var client = new HttpClient();
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      response.listen((_) {}).cancel();
    });
  });
}

void main() {
  testDefaultResponseHeaders();
  testDefaultResponseHeadersContentType();
  testListenOn();
  testHttpServerZone();
  testHttpServerZoneError();
  testHttpServerClientClose();
}
