// 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.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

import "dart:async";
import "dart:isolate";
import "dart:io";
import "package:expect/expect.dart";

void testNoBody(int totalConnections, bool explicitContentLength) {
  int count = 0;
  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
    server.listen((HttpRequest request) {
      Expect.equals(null, request.headers.value('content-length'));
      Expect.equals(-1, request.contentLength);
      var response = request.response;
      response.contentLength = 0;
      response.done.then((_) {
        Expect.fail("Unexpected successful response completion");
      }).catchError((error) {
        Expect.isTrue(error is HttpException);
        if (++count == totalConnections) {
          server.close();
        }
      });
      // write with content length 0 closes the connection and
      // reports an error.
      response.write("x");
      // Subsequent write are ignored as there is already an
      // error.
      response.write("x");
      // After an explicit close, write becomes a state error
      // because we have said we will not add more.
      response.close();
      Expect.throws(() {
        response.write("x");
      }, (e) => e is StateError);
    }, onError: (e, trace) {
      String msg = "Unexpected server error $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    });

    HttpClient client = new HttpClient();
    for (int i = 0; i < totalConnections; i++) {
      client.get("127.0.0.1", server.port, "/").then((request) {
        if (explicitContentLength) {
          request.contentLength = 0;
        }
        return request.close();
      }).then((response) {
        Expect.equals("0", response.headers.value('content-length'));
        Expect.equals(0, response.contentLength);
        response.drain();
      }).catchError((e, trace) {
        // It's also okay to fail, as headers may not be written.
      });
    }
  });
}

void testBody(int totalConnections, bool useHeader) {
  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
    int serverCount = 0;
    server.listen((HttpRequest request) {
      Expect.equals("2", request.headers.value('content-length'));
      Expect.equals(2, request.contentLength);
      var response = request.response;
      if (useHeader) {
        response.contentLength = 2;
      } else {
        response.headers.set("content-length", 2);
      }
      request.listen((d) {}, onDone: () {
        response.write("x");
        Expect.throws(
            () => response.contentLength = 3, (e) => e is HttpException);
        response.write("x");
        response.write("x");
        response.done.then((_) {
          Expect.fail("Unexpected successful response completion");
        }).catchError((error) {
          Expect.isTrue(error is HttpException, "[$error]");
          if (++serverCount == totalConnections) {
            server.close();
          }
        });
        response.close();
        Expect.throws(() {
          response.write("x");
        }, (e) => e is StateError);
      });
    }, onError: (e, trace) {
      String msg = "Unexpected error $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    });

    int clientCount = 0;
    HttpClient client = new HttpClient();
    for (int i = 0; i < totalConnections; i++) {
      client.get("127.0.0.1", server.port, "/").then((request) {
        if (useHeader) {
          request.contentLength = 2;
        } else {
          request.headers.add(HttpHeaders.contentLengthHeader, "7");
          request.headers.add(HttpHeaders.contentLengthHeader, "2");
        }
        request.write("x");
        Expect.throws(
            () => request.contentLength = 3, (e) => e is HttpException);
        request.write("x");
        return request.close();
      }).then((response) {
        Expect.equals("2", response.headers.value('content-length'));
        Expect.equals(2, response.contentLength);
        response.listen((d) {}, onDone: () {
          if (++clientCount == totalConnections) {
            client.close();
          }
        }, onError: (error, trace) {
          // Undefined what server response sends.
        });
      }).catchError((error) {
        // It's also okay to fail, as headers may not be written.
      });
    }
  });
}

void testBodyChunked(int totalConnections, bool useHeader) {
  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
    server.listen((HttpRequest request) {
      Expect.isNull(request.headers.value('content-length'));
      Expect.equals(-1, request.contentLength);
      var response = request.response;
      if (useHeader) {
        response.contentLength = 2;
        response.headers.chunkedTransferEncoding = true;
      } else {
        response.headers.set("content-length", 2);
        response.headers.set("transfer-encoding", "chunked");
      }
      request.listen((d) {}, onDone: () {
        response.write("x");
        Expect.throws(() => response.headers.chunkedTransferEncoding = false,
            (e) => e is HttpException);
        response.write("x");
        response.write("x");
        response.close();
        Expect.throws(() {
          response.write("x");
        }, (e) => e is StateError);
      });
    }, onError: (e, trace) {
      String msg = "Unexpected error $e";
      if (trace != null) msg += "\nStackTrace: $trace";
      Expect.fail(msg);
    });

    int count = 0;
    HttpClient client = new HttpClient();
    for (int i = 0; i < totalConnections; i++) {
      client.get("127.0.0.1", server.port, "/").then((request) {
        if (useHeader) {
          request.contentLength = 2;
          request.headers.chunkedTransferEncoding = true;
        } else {
          request.headers.add(HttpHeaders.contentLengthHeader, "2");
          request.headers.set(HttpHeaders.transferEncodingHeader, "chunked");
        }
        request.write("x");
        Expect.throws(() => request.headers.chunkedTransferEncoding = false,
            (e) => e is HttpException);
        request.write("x");
        request.write("x");
        return request.close();
      }).then((response) {
        Expect.isNull(response.headers.value('content-length'));
        Expect.equals(-1, response.contentLength);
        response.listen((d) {}, onDone: () {
          if (++count == totalConnections) {
            client.close();
            server.close();
          }
        });
      }).catchError((e, trace) {
        String msg = "Unexpected error $e";
        if (trace != null) msg += "\nStackTrace: $trace";
        Expect.fail(msg);
      });
    }
  });
}

void testSetContentLength() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((HttpRequest request) {
      var response = request.response;
      Expect.isNull(response.headers.value('content-length'));
      Expect.equals(-1, response.contentLength);
      response.headers.set("content-length", 3);
      Expect.equals("3", response.headers.value('content-length'));
      Expect.equals(3, response.contentLength);
      response.write("xxx");
      response.close();
    });

    var client = new HttpClient();
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      response.listen((_) {}, onDone: () {
        client.close();
        server.close();
      });
    });
  });
}

void main() {
  testNoBody(5, false);
  testNoBody(25, false);
  testNoBody(5, true);
  testNoBody(25, true);
  testBody(5, false);
  testBody(5, true);
  testBodyChunked(5, false);
  testBodyChunked(5, true);
  testSetContentLength();
}
