// Copyright (c) 2018, 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:io' show ServerSocket, Socket;

import 'package:http_io/http_io.dart';
import 'package:test/test.dart';

Future<Null> testServerDetachSocket() {
  final completer = new Completer<Null>();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.defaultResponseHeaders.clear();
    server.serverHeader = null;
    server.listen((request) {
      var response = request.response;
      response.contentLength = 0;
      response.detachSocket().then((socket) {
        expect(socket, isNotNull);
        var body = new StringBuffer();
        socket.listen((data) => body.write(new String.fromCharCodes(data)),
            onDone: () => expect("Some data", body.toString()));
        socket.write("Test!");
        socket.close();
      });
      server.close();
      completer.complete();
    });

    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.write("GET / HTTP/1.1\r\n"
          "content-length: 0\r\n\r\n"
          "Some data");
      var body = new StringBuffer();
      socket.listen((data) => body.write(new String.fromCharCodes(data)),
          onDone: () {
        expect(
            "HTTP/1.1 200 OK\r\n"
            "content-length: 0\r\n"
            "\r\n"
            "Test!",
            body.toString());
        socket.close();
      });
    });
  });
  return completer.future;
}

Future<Null> testServerDetachSocketNoWriteHeaders() {
  final completer = new Completer<Null>();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      var response = request.response;
      response.contentLength = 0;
      response.detachSocket(writeHeaders: false).then((socket) {
        expect(socket, isNotNull);
        var body = new StringBuffer();
        socket.listen((data) => body.write(new String.fromCharCodes(data)),
            onDone: () => expect("Some data", body.toString()));
        socket.write("Test!");
        socket.close();
      });
      server.close();
      completer.complete();
    });

    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.write("GET / HTTP/1.1\r\n"
          "content-length: 0\r\n\r\n"
          "Some data");
      var body = new StringBuffer();
      socket.listen((data) => body.write(new String.fromCharCodes(data)),
          onDone: () {
        expect("Test!", body.toString());
        socket.close();
      });
    });
  });
  return completer.future;
}

Future<Null> testBadServerDetachSocket() {
  final completer = new Completer<Null>();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      var response = request.response;
      response.contentLength = 0;
      response.close();
      expect(response.detachSocket, throwsA(new TypeMatcher<StateError>()));
      server.close();
      completer.complete();
    });

    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.write("GET / HTTP/1.1\r\n"
          "content-length: 0\r\n\r\n");
      socket.listen((_) {}, onDone: () {
        socket.close();
      });
    });
  });
  return completer.future;
}

Future<Null> testClientDetachSocket() {
  final completer = new Completer<Null>();
  ServerSocket.bind("127.0.0.1", 0).then((server) {
    server.listen((socket) {
      int port = server.port;
      socket.write("HTTP/1.1 200 OK\r\n"
          "\r\n"
          "Test!");
      var body = new StringBuffer();
      socket.listen((data) => body.write(new String.fromCharCodes(data)),
          onDone: () {
        List<String> lines = body.toString().split("\r\n");
        expect(6, lines.length);
        expect("GET / HTTP/1.1", lines[0]);
        expect("", lines[4]);
        expect("Some data", lines[5]);
        lines.sort(); // Lines 1-3 becomes 3-5 in a fixed order.
        expect("accept-encoding: gzip", lines[3]);
        expect("content-length: 0", lines[4]);
        expect("host: 127.0.0.1:$port", lines[5]);
        socket.close();
      });
      server.close();
      completer.complete();
    });

    var client = new HttpClient();
    client.userAgent = null;
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      response.detachSocket().then((socket) {
        var body = new StringBuffer();
        socket.listen((data) => body.write(new String.fromCharCodes(data)),
            onDone: () {
          expect("Test!", body.toString());
          client.close();
        });
        socket.write("Some data");
        socket.close();
      });
    });
  });
  return completer.future;
}

Future<Null> testUpgradedConnection() {
  final completer = new Completer<Null>();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      request.response.headers.set('connection', 'upgrade');
      if (request.headers.value('upgrade') == 'mine') {
        request.response.detachSocket().then((socket) {
          socket.cast<List<int>>().pipe(socket).then((_) {});
        });
      } else {
        request.response.close();
      }
    });

    var client = new HttpClient();
    client.userAgent = null;
    client.get("127.0.0.1", server.port, "/").then((request) {
      request.headers.set('upgrade', 'mine');
      return request.close();
    }).then((response) {
      client.get("127.0.0.1", server.port, "/").then((request) {
        response.detachSocket().then((socket) {
          // We are testing that we can detach the socket, even though
          // we made a new connection (testing it was not reused).
          request.close().then((response) {
            response.listen(null, onDone: () {
              server.close();
              completer.complete();
            });
            socket.add([0]);
            socket.close();
            socket.fold([], (l, d) => l..addAll(d)).then((data) {
              expect([0], data);
            });
          });
        });
      });
    });
  });
  return completer.future;
}

void main() {
  test('serverDetachSocket', testServerDetachSocket);
  test(
      'serverDetachSocketNoWriteHeaders', testServerDetachSocketNoWriteHeaders);
  test('badServerDetachSocket', testBadServerDetachSocket);
  test('clientDetachSocket', testClientDetachSocket);
  test('upgradedConnection', testUpgradedConnection);
}
