// 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:expect/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<List<int>>([], (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() {
  late ServerSocket socket;
  late 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();
}
