// 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>.filled(messageSize, 0);

      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>.filled(messageSize, 0);

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