// 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 'package:expect/expect.dart';
import 'dart:io';
import 'dart:typed_data';

void testServerCompress({bool clientAutoUncompress: true}) {
  void test(List<int> data) {
    HttpServer.bind("127.0.0.1", 0).then((server) {
      server.autoCompress = true;
      server.listen((request) {
        request.response.add(data);
        request.response.close();
      });
      var client = new HttpClient();
      client.autoUncompress = clientAutoUncompress;
      client.get("127.0.0.1", server.port, "/").then((request) {
        request.headers.set(HttpHeaders.acceptEncodingHeader, "gzip,deflate");
        return request.close();
      }).then((response) {
        Expect.equals(
            "gzip", response.headers.value(HttpHeaders.contentEncodingHeader));
        response.fold([], (list, b) {
          list.addAll(b);
          return list;
        }).then((list) {
          if (clientAutoUncompress) {
            Expect.listEquals(data, list);
          } else {
            Expect.listEquals(data, gzip.decode(list));
          }
          server.close();
          client.close();
        });
      });
    });
  }

  test("My raw server provided data".codeUnits);
  var longBuffer = new Uint8List(1024 * 1024);
  for (int i = 0; i < longBuffer.length; i++) {
    longBuffer[i] = i & 0xFF;
  }
  test(longBuffer);
}

void testAcceptEncodingHeader() {
  void test(String encoding, bool valid) {
    HttpServer.bind("127.0.0.1", 0).then((server) {
      server.autoCompress = true;
      server.listen((request) {
        request.response.write("data");
        request.response.close();
      });
      var client = new HttpClient();
      client.get("127.0.0.1", server.port, "/").then((request) {
        request.headers.set(HttpHeaders.acceptEncodingHeader, encoding);
        return request.close();
      }).then((response) {
        Expect.equals(
            valid,
            ("gzip" ==
                response.headers.value(HttpHeaders.contentEncodingHeader)));
        response.listen((_) {}, onDone: () {
          server.close();
          client.close();
        });
      });
    });
  }

  test('gzip', true);
  test('deflate', false);
  test('gzip, deflate', true);
  test('gzip ,deflate', true);
  test('gzip  ,  deflate', true);
  test('deflate,gzip', true);
  test('deflate, gzip', true);
  test('deflate ,gzip', true);
  test('deflate  ,  gzip', true);
  test('abc,deflate  ,  gzip,def,,,ghi  ,jkl', true);
  test('xgzip', false);
  test('gzipx;', false);
}

void testDisableCompressTest() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    Expect.equals(false, server.autoCompress);
    server.listen((request) {
      Expect.equals(
          'gzip', request.headers.value(HttpHeaders.acceptEncodingHeader));
      request.response.write("data");
      request.response.close();
    });
    var client = new HttpClient();
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      Expect.equals(
          null, response.headers.value(HttpHeaders.contentEncodingHeader));
      response.listen((_) {}, onDone: () {
        server.close();
        client.close();
      });
    });
  });
}

void main() {
  testServerCompress();
  testServerCompress(clientAutoUncompress: false);
  testAcceptEncodingHeader();
  testDisableCompressTest();
}
