// 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";

void testArguments() {
  Expect.throws(() => ServerSocket.bind("127.0.0.1", 65536));
  Expect.throws(() => ServerSocket.bind("127.0.0.1", -1));
  Expect.throws(() => ServerSocket.bind("127.0.0.1", 0, backlog: -1));
}

void testSimpleBind() {
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((s) {
    Expect.isTrue(s.port > 0);
    port.close();
  });
}

void testInvalidBind() {
  int count = 0;
  ReceivePort port = new ReceivePort();
  port.receive((_, __) { count++; if (count == 3) port.close(); });

  // Bind to a unknown DNS name.
  ServerSocket.bind("ko.faar.__hest__", 0)
      .then((_) { Expect.fail("Failure expected"); } )
      .catchError((error) {
        Expect.isTrue(error is SocketException);
        port.toSendPort().send(1);
      });

  // Bind to an unavaliable IP-address.
  ServerSocket.bind("8.8.8.8", 0)
      .then((_) { Expect.fail("Failure expected"); } )
      .catchError((error) {
        Expect.isTrue(error is SocketException);
        port.toSendPort().send(1);
      });

  // Bind to a port already in use.
  ServerSocket.bind("127.0.0.1", 0)
      .then((s) {
        ServerSocket.bind("127.0.0.1", s.port)
            .then((t) {
              Expect.fail("Multiple listens on same port");
              port.toSendPort().send(1);
            })
            .catchError((error) {
              Expect.isTrue(error is SocketException);
              s.close();
              port.toSendPort().send(1);
            });
      });
}

void testConnectNoDestroy() {
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen((_) { });
    Socket.connect("127.0.0.1", server.port).then((_) {
      server.close();
      port.close();
    });
  });
}

void testConnectImmediateDestroy() {
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen((_) { });
    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.destroy();
      server.close();
      port.close();
    });
  });
}

void testConnectConsumerClose() {
  // Connect socket then immediate close the consumer without
  // listening on the stream.
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen((_) { });
    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.close();
      socket.done.then((_) {
        socket.destroy();
        server.close();
        port.close();
      });
    });
  });
}

void testConnectConsumerWriteClose() {
  // Connect socket write some data immediate close the consumer
  // without listening on the stream.
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen((_) { });
    Socket.connect("127.0.0.1", server.port).then((socket) {
      socket.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
      socket.close();
      socket.done.then((_) {
        socket.destroy();
        server.close();
        port.close();
      });
    });
  });
}

void testConnectStreamClose() {
  // Connect socket and listen on the stream. The server closes
  // immediately so only a done event is received.
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen((client) {
                    client.close();
                    client.done.then((_) => client.destroy());
                  });
    Socket.connect("127.0.0.1", server.port).then((socket) {
        bool onDoneCalled = false;
        socket.listen((_) { Expect.fail("Unexpected data"); },
                      onDone: () {
                        Expect.isFalse(onDoneCalled);
                        onDoneCalled = true;
                        socket.close();
                        server.close();
                        port.close();
                      });
    });
  });
}

void testConnectStreamDataClose(bool useDestroy) {
  // Connect socket and listen on the stream. The server sends data
  // and then closes so both data and a done event is received.
  List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen(
        (client) {
          client.add(sendData);
          if (useDestroy) {
            client.destroy();
          } else {
            client.close();
          }
          client.done.then((_) { if (!useDestroy) { client.destroy(); } });
        });
    Socket.connect("127.0.0.1", server.port).then((socket) {
        List<int> data = [];
        bool onDoneCalled = false;
        socket.listen(data.addAll,
                      onDone: () {
                        Expect.isFalse(onDoneCalled);
                        onDoneCalled = true;
                        if (!useDestroy) Expect.listEquals(sendData, data);
                        socket.add([0]);
                        socket.close();
                        server.close();
                        port.close();
                      });
    });
  });
}

void testConnectStreamDataCloseCancel(bool useDestroy) {
  List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  ReceivePort port = new ReceivePort();
  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
    server.listen(
        (client) {
          client.add(sendData);
          if (useDestroy) {
            client.destroy();
          } else {
            client.close();
          }
          client.done
              .then((_) {
                if (!useDestroy) client.destroy();
              })
              .catchError((e) { /* can happen with short writes */ });
        });
    Socket.connect("127.0.0.1", server.port).then((socket) {
        List<int> data = [];
        bool onDoneCalled = false;
        var subscription;
        subscription = socket.listen(
            (_) {
              subscription.cancel();
              socket.close();
              server.close();
              port.close();
            },
            onDone: () { Expect.fail("Unexpected pipe completion"); });
    });
  });
}

main() {
  testArguments();
  testSimpleBind();
  testInvalidBind();
  testConnectNoDestroy();
  testConnectImmediateDestroy();
  testConnectConsumerClose();
  testConnectConsumerWriteClose();
  testConnectStreamClose();
  testConnectStreamDataClose(true);
  testConnectStreamDataClose(false);
  testConnectStreamDataCloseCancel(true);
  testConnectStreamDataCloseCancel(false);
}
