// 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:async";
import "dart:io";
import "dart:isolate";
import "dart:typed_data";

Future<HttpServer> createServer() => HttpServer.bind("127.0.0.1", 0);

Future<WebSocket> createClient(int port, bool compression) => compression
    ? WebSocket.connect('ws://127.0.0.1:$port/')
    : WebSocket.connect('ws://127.0.0.1:$port/',
        compression: CompressionOptions.OFF);

void test(expected, testData, compression) {
  createServer().then((server) {
    var messageCount = 0;
    var transformer = compression
        ? new WebSocketTransformer()
        : new WebSocketTransformer(compression: CompressionOptions.OFF);
    server.transform(transformer).listen((webSocket) {
      webSocket.listen((message) {
        Expect.listEquals(expected, message);
        webSocket.add(testData[messageCount]);
        messageCount++;
      }, onDone: () => Expect.equals(testData.length, messageCount));
    });

    createClient(server.port, compression).then((webSocket) {
      var messageCount = 0;
      webSocket.listen((message) {
        Expect.listEquals(expected, message);
        messageCount++;
        if (messageCount == testData.length) webSocket.close();
      }, onDone: server.close);
      testData.forEach(webSocket.add);
    });
  });
}

testUintLists({bool compression: false}) {
  var fillData = new List.generate(256, (index) => index);
  var testData = [
    new Uint8List(256),
    new Uint8ClampedList(256),
    new Uint16List(256),
    new Uint32List(256),
    new Uint64List(256),
  ];
  testData.forEach((list) => list.setAll(0, fillData));
  test(fillData, testData, compression);
}

testIntLists({bool compression: false}) {
  var fillData = new List.generate(128, (index) => index);
  var testData = [
    new Int8List(128),
    new Int16List(128),
    new Int32List(128),
    new Int64List(128),
  ];
  testData.forEach((list) => list.setAll(0, fillData));
  test(fillData, testData, compression);
}

void testOutOfRangeClient({bool compression: false}) {
  createServer().then((server) {
    var messageCount = 0;
    var transformer = compression
        ? new WebSocketTransformer()
        : new WebSocketTransformer(compression: CompressionOptions.OFF);
    server.transform(transformer).listen((webSocket) {
      webSocket.listen((message) => Expect.fail("No message expected"));
    });

    Future clientError(data) {
      return createClient(server.port, compression).then((webSocket) {
        var messageCount = 0;
        webSocket.listen((message) => Expect.fail("No message expected"));
        webSocket.add(data);
        webSocket.close();
        return webSocket.done;
      });
    }

    Future expectError(data) {
      var completer = new Completer();
      clientError(data)
          .then((_) => completer.completeError("Message $data did not fail"))
          .catchError((e) => completer.complete(true));
      return completer.future;
    }

    var futures = [];
    var data;
    data = new Uint16List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data = new Uint32List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data = new Uint64List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data = new Int16List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data[0] = -1;
    futures.add(expectError(data));
    data = new Int32List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data[0] = -1;
    futures.add(expectError(data));
    data = new Int64List(1);
    data[0] = 256;
    futures.add(expectError(data));
    data[0] = -1;
    futures.add(expectError(data));
    futures.add(expectError([-1]));
    futures.add(expectError([256]));

    Future.wait(futures).then((_) => server.close());
  });
}

void testOutOfRangeServer({bool compression: false}) {
  var futures = [];
  var testData = [];
  var data;
  data = new Uint16List(1);
  data[0] = 256;
  testData.add(data);
  data = new Uint32List(1);
  data[0] = 256;
  testData.add(data);
  data = new Uint64List(1);
  data[0] = 256;
  testData.add(data);
  data = new Int16List(1);
  data[0] = 256;
  testData.add(data);
  data = new Int16List(1);
  data[0] = -1;
  testData.add(data);
  data = new Int32List(1);
  data[0] = 256;
  testData.add(data);
  data = new Int32List(1);
  data[0] = -1;
  testData.add(data);
  data = new Int64List(1);
  data[0] = 256;
  testData.add(data);
  data = new Int64List(1);
  data[0] = -1;
  testData.add(data);
  testData.add([-1]);
  testData.add([256]);

  var allDone = new Completer();

  Future expectError(future) {
    var completer = new Completer();
    future
        .then((_) => completer.completeError("Message $data did not fail"))
        .catchError((e) => completer.complete(true));
    return completer.future;
  }

  createServer().then((server) {
    var messageCount = 0;
    var transformer = compression
        ? new WebSocketTransformer()
        : new WebSocketTransformer(compression: CompressionOptions.OFF);
    server.transform(transformer).listen((webSocket) {
      webSocket.listen((message) {
        messageCount++;
        webSocket.add(testData[message[0]]);
        webSocket.close();
        futures.add(expectError(webSocket.done));
        if (messageCount == testData.length) allDone.complete(true);
      });
    });

    Future x(int i) {
      var completer = new Completer();
      createClient(server.port, compression).then((webSocket) {
        webSocket.listen((message) => Expect.fail("No message expected"),
            onDone: () => completer.complete(true),
            onError: (e) => completer.completeError(e));
        webSocket.add(new List()..add(i));
      });
      return completer.future;
    }

    for (int i = 0; i < testData.length; i++) futures.add(x(i));
    allDone.future
        .then((_) => Future.wait(futures).then((_) => server.close()));
  });
}

main() {
  testUintLists();
  testUintLists(compression: true);
  testIntLists();
  testIntLists(compression: true);
  testOutOfRangeClient();
  testOutOfRangeClient(compression: true);
  // testOutOfRangeServer();
  // testOutOfRangeServer(compression: true);
}
