// 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) =>
  WebSocket.connect('ws://127.0.0.1:$port/');

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

    createClient(server.port).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() {
  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);
}

testIntLists() {
  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);
}

void testOutOfRangeClient() {
  createServer().then((server) {
    var messageCount = 0;
    server.transform(new WebSocketTransformer()).listen((webSocket) {
      webSocket.listen((message) => Expect.fail("No message expected"));
    });

    Future clientError(data) {
      return createClient(server.port).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() {
  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;
    server.transform(new WebSocketTransformer()).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).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();
  testIntLists();
  testOutOfRangeClient();
  testOutOfRangeServer();
}
