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

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

testOutOfRange() {
  asyncStart();
  RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
    server.listen((client) {
      client.writeEventsEnabled = false;
      client.listen((event) {
        switch (event) {
          case RawSocketEvent.read:
            Expect.fail("No data expected");
            break;
          case RawSocketEvent.write:
            break;
          case RawSocketEvent.readClosed:
            client.close();
            server.close();
            break;
          case RawSocketEvent.closed:
            break;
          default:
            throw "Unexpected event $event";
        }
      });
    });

    RawSocket.connect("127.0.0.1", server.port).then((socket) {
      socket.listen((event) {
        switch (event) {
          case RawSocketEvent.read:
            break;
          case RawSocketEvent.write:
            Expect.isFalse(socket.writeEventsEnabled);
            var data;
            data = new Uint16List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data = new Uint32List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data = new Uint64List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data = new Int16List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data[0] = -1;
            Expect.throws(() => socket.write(data));
            data = new Int32List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data[0] = -1;
            Expect.throws(() => socket.write(data));
            data = new Int64List(1);
            data[0] = 256;
            Expect.throws(() => socket.write(data));
            data[0] = -1;
            Expect.throws(() => socket.write(data));
            Expect.throws(() => socket.write([-1]));
            Expect.throws(() => socket.write([256]));
            socket.close();
            break;
          case RawSocketEvent.readClosed:
            break;
          case RawSocketEvent.closed:
            break;
          default:
            throw "Unexpected event $event";
        }
      }, onDone: asyncEnd);
    });
  });
}

void testSimpleReadWrite() {
  // This test creates a server and a client connects. The client then
  // writes and the server echos. When the server has finished its
  // echo it half-closes. When the client gets the close event is
  // closes fully.
  asyncStart();

  // The test data to send is 5 times 256 bytes and 4 times 128
  // bytes. This is all the legal byte values from the integer typed
  // data.
  const messageSize = 256 * 5 + 128 * 4;
  var fillData128 = new List.generate(128, (index) => index);
  var fillData256 = new List.generate(256, (index) => index);
  List<List<int>> createTestData() {
    return [
      new Uint8List(256)..setAll(0, fillData256),
      new Uint8ClampedList(256)..setAll(0, fillData256),
      new Uint16List(256)..setAll(0, fillData256),
      new Uint32List(256)..setAll(0, fillData256),
      new Uint64List(256)..setAll(0, fillData256),
      new Int8List(128)..setAll(0, fillData128),
      new Int16List(128)..setAll(0, fillData128),
      new Int32List(128)..setAll(0, fillData128),
      new Int64List(128)..setAll(0, fillData128),
    ];
  }

  void verifyTestData(List<int> data) {
    var testData = createTestData();
    var expected = [];
    testData.forEach((list) => expected.addAll(list));
    Expect.listEquals(expected, data);
  }

  RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
    server.listen((client) {
      int bytesRead = 0;
      int bytesWritten = 0;
      int index = 0;
      List<List<int>> data = createTestData();
      List<int> received = new List<int>(messageSize);

      client.writeEventsEnabled = false;
      client.listen((event) {
        switch (event) {
          case RawSocketEvent.read:
            Expect.isTrue(bytesWritten == 0);
            Expect.isTrue(client.available() > 0);
            var buffer = client.read();
            received.setRange(bytesRead, bytesRead + buffer.length, buffer);
            bytesRead += buffer.length;
            if (bytesRead == messageSize) {
              verifyTestData(received);
              client.writeEventsEnabled = true;
            }
            break;
          case RawSocketEvent.write:
            Expect.isTrue(bytesRead == messageSize);
            Expect.isFalse(client.writeEventsEnabled);
            bytesWritten += client.write(
                data[index], bytesWritten, data[index].length - bytesWritten);
            if (bytesWritten < data[index].length) {
              client.writeEventsEnabled = true;
            } else {
              index++;
              bytesWritten = 0;
              if (index < data.length) {
                client.writeEventsEnabled = true;
              } else {
                client.shutdown(SocketDirection.send);
              }
            }
            break;
          case RawSocketEvent.readClosed:
            server.close();
            break;
          case RawSocketEvent.closed:
            break;
          default:
            throw "Unexpected event $event";
        }
      });
    });

    RawSocket.connect("127.0.0.1", server.port).then((socket) {
      int bytesRead = 0;
      int bytesWritten = 0;
      int index = 0;
      List<List<int>> data = createTestData();
      List<int> received = new List<int>(messageSize);

      socket.listen((event) {
        switch (event) {
          case RawSocketEvent.read:
            Expect.isTrue(socket.available() > 0);
            var buffer = socket.read();
            received.setRange(bytesRead, bytesRead + buffer.length, buffer);
            bytesRead += buffer.length;
            break;
          case RawSocketEvent.write:
            Expect.isTrue(bytesRead == 0);
            Expect.isFalse(socket.writeEventsEnabled);
            bytesWritten += socket.write(
                data[index], bytesWritten, data[index].length - bytesWritten);
            if (bytesWritten < data[index].length) {
              socket.writeEventsEnabled = true;
            } else {
              index++;
              bytesWritten = 0;
              if (index < data.length) {
                socket.writeEventsEnabled = true;
              }
            }
            break;
          case RawSocketEvent.readClosed:
            verifyTestData(received);
            socket.close();
            break;
          case RawSocketEvent.closed:
            break;
          default:
            throw "Unexpected event $event";
        }
      }, onDone: asyncEnd);
    });
  });
}

main() {
  // testOutOfRange();
  testSimpleReadWrite();
}
