// 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.

import "dart:async";
import "dart:io";
import "dart:typed_data";

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

class FutureExpect {
  static Future check(Future result, check) =>
      result.then((value) => check(value));
  static Future throws(Future result) =>
      result.then((value) {
        throw new ExpectException(
            "FutureExpect.throws received $value instead of an exception");
        }, onError: (_) => null);
}

testDatagramBroadcastOptions() {
  test(address) {
    asyncStart();
    RawDatagramSocket.bind(address, 0).then((socket) {
      Expect.isFalse(socket.broadcastEnabled);
      socket.broadcastEnabled = true;
      if (!Platform.isMacOS) {
        Expect.isTrue(socket.broadcastEnabled);
      }
      socket.broadcastEnabled = false;
      Expect.isFalse(socket.broadcastEnabled);
      asyncEnd();
    });
  }

  test(InternetAddress.LOOPBACK_IP_V4);
  test(InternetAddress.ANY_IP_V4);
}

testDatagramMulticastOptions() {
  test(address) {
    asyncStart();
    RawDatagramSocket.bind(address, 0).then((socket) {
      Expect.isTrue(socket.multicastLoopback);
      Expect.equals(1, socket.multicastHops);
      Expect.throws(() => socket.multicastInterface);

      socket.multicastLoopback = false;
      socket.multicastHops = 4;
      Expect.isFalse(socket.multicastLoopback);
      Expect.equals(4, socket.multicastHops);
      Expect.throws(() => socket.multicastInterface = null);

      socket.multicastLoopback = true;
      socket.multicastHops = 1;
      Expect.isTrue(socket.multicastLoopback);
      Expect.equals(1, socket.multicastHops);
      Expect.throws(() => socket.multicastInterface);

      asyncEnd();
    });
  }

  test(InternetAddress.LOOPBACK_IP_V4);
  test(InternetAddress.ANY_IP_V4);
  test(InternetAddress.LOOPBACK_IP_V6);
  test(InternetAddress.ANY_IP_V6);
}

testDatagramSocketReuseAddress() {
  test(address, reuseAddress) {
    asyncStart();
    RawDatagramSocket.bind(
        address, 0, reuseAddress: reuseAddress).then((socket) {
            if (reuseAddress) {
              RawDatagramSocket.bind(address, socket.port)
                  .then((s) => Expect.isTrue(s is RawDatagramSocket))
                  .then(asyncSuccess);
            } else {
              FutureExpect.throws(RawDatagramSocket.bind(address, socket.port))
                  .then(asyncSuccess);
            }
    });
  }

  test(InternetAddress.LOOPBACK_IP_V4, true);
  test(InternetAddress.LOOPBACK_IP_V4, false);
  test(InternetAddress.LOOPBACK_IP_V6, true);
  test(InternetAddress.LOOPBACK_IP_V6, false);
}

testBroadcast() {
  test(bindAddress, broadcastAddress, enabled) {
    asyncStart();
    Future.wait([
        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
      .then((values) {
        var broadcastTimer;
        var sender = values[0];
        var receiver = values[1];
        // On Windows at least the receiver needs to have broadcast
        // enabled whereas on Linux at least the sender needs to.
        receiver.broadcastEnabled = enabled;
        sender.broadcastEnabled = enabled;
        receiver.listen((event) {
          if (event == RawSocketEvent.READ) {
            Expect.isTrue(enabled);
            sender.close();
            receiver.close();
            broadcastTimer.cancel();
            asyncEnd();
          }
        });

        int sendCount = 0;
        send(_) {
          int bytes =
              sender.send(new Uint8List(1), broadcastAddress, receiver.port);
          Expect.isTrue(bytes == 0 || bytes == 1);
          sendCount++;
          if (!enabled && sendCount == 50) {
            sender.close();
            receiver.close();
            broadcastTimer.cancel();
            asyncEnd();
          }
        }
        broadcastTimer = new Timer.periodic(new Duration(milliseconds: 10), send);
      });
  }

  var broadcast = new InternetAddress("255.255.255.255");
  test(InternetAddress.ANY_IP_V4, broadcast, false);
  test(InternetAddress.ANY_IP_V4, broadcast, true);
}

testLoopbackMulticast() {
  test(bindAddress, multicastAddress, enabled) {
    asyncStart();
    Future.wait([
        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
        RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
      .then((values) {
        var senderTimer;
        var sender = values[0];
        var receiver = values[1];

        sender.joinMulticast(multicastAddress);
        receiver.joinMulticast(multicastAddress);
        // On Windows at least the receiver needs to have multicast
        // loop enabled whereas on Linux at least the sender needs to.
        receiver.multicastLoopback = enabled;
        sender.multicastLoopback = enabled;

        receiver.listen((event) {
          if (event == RawSocketEvent.READ) {
            if (!enabled) {
              var data = receiver.receive();
              print(data.port);
              print(data.address);
            }
            Expect.isTrue(enabled);
            sender.close();
            receiver.close();
            senderTimer.cancel();
            asyncEnd();
          }
        });

        int sendCount = 0;
        send(_) {
          int bytes =
              sender.send(new Uint8List(1), multicastAddress, receiver.port);
          Expect.isTrue(bytes == 0 || bytes == 1);
          sendCount++;
          if (!enabled && sendCount == 50) {
            sender.close();
            receiver.close();
            senderTimer.cancel();
            asyncEnd();
          }
        }
        senderTimer = new Timer.periodic(new Duration(milliseconds: 10), send);
      });
  }

  test(InternetAddress.ANY_IP_V4, new InternetAddress("228.0.0.4"), true);
  test(InternetAddress.ANY_IP_V4, new InternetAddress("224.0.0.0"), false);
  if (!Platform.isMacOS) {
    test(InternetAddress.ANY_IP_V6, new InternetAddress("ff11::0"), true);
    test(InternetAddress.ANY_IP_V6, new InternetAddress("ff11::0"), false);
  }
}

testSendReceive(InternetAddress bindAddress) {
  asyncStart();

  var total = 1000;

  int receivedSeq = 0;

  var ackSeq = 0;
  Timer ackTimer;

  Future.wait([
      RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
      RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
    .then((values) {
      var sender = values[0];
      var receiver = values[1];
      if (bindAddress.isMulticast) {
        sender.multicastLoopback = true;
        receiver.multicastLoopback = true;
        sender.joinMulticast(bindAddress);
        receiver.joinMulticast(bindAddress);
      }

      Uint8List createDataPackage(int seq) {
        var data = new Uint8List(1000);
        (new ByteData.view(data.buffer, 0, 4)).setUint32(0, seq);
        return data;
      }

      Uint8List createAckPackage(int seq) {
        var data = new Uint8List(4);
        new ByteData.view(data.buffer, 0, 4).setUint32(0, seq);
        return data;
      }

      int packageSeq(Datagram datagram) =>
          new ByteData.view((datagram.data as Uint8List).buffer).getUint32(0);

      void sendData(int seq) {
        // Send a datagram acknowledging the received sequence.
        int bytes = sender.send(
            createDataPackage(seq), bindAddress, receiver.port);
        Expect.isTrue(bytes == 0 || bytes == 1000);
      }

      void sendAck(address, port) {
        // Send a datagram acknowledging the received sequence.
        int bytes = receiver.send(createAckPackage(receivedSeq), address, port);
        Expect.isTrue(bytes == 0 || bytes == 4);
        // Start a "long" timer for more data.
        if (ackTimer != null) ackTimer.cancel();
        ackTimer = new Timer.periodic(
            new Duration(milliseconds: 100), (_) => sendAck(address, port));
      }

      sender.listen((event) {
        switch (event) {
          case RawSocketEvent.READ:
            var datagram = sender.receive();
            if (datagram != null) {
              Expect.equals(datagram.port, receiver.port);
              if (!bindAddress.isMulticast) {
                Expect.equals(receiver.address, datagram.address);
              }
              ackSeq = packageSeq(datagram);
              if (ackSeq < total) {
                sender.writeEventsEnabled = true;
              } else {
                sender.close();
                receiver.close();
                ackTimer.cancel();
                asyncEnd();
              }
            }
            break;
          case RawSocketEvent.WRITE:
            // Send the next package.
            sendData(ackSeq + 1);
            break;
          case RawSocketEvent.CLOSED:
            break;
          default:
            throw "Unexpected event $event";
        }
      });

      receiver.writeEventsEnabled = false;
      receiver.listen((event) {
        switch (event) {
          case RawSocketEvent.READ:
            var datagram = receiver.receive();
            if (datagram != null) {
              Expect.equals(datagram.port, sender.port);
              if (!bindAddress.isMulticast) {
                Expect.equals(receiver.address, datagram.address);
              }
              var seq = packageSeq(datagram);
              if (seq == receivedSeq + 1) {
                receivedSeq = seq;
                sendAck(bindAddress, sender.port);
              }
            }
            break;
          case RawSocketEvent.WRITE:
            throw "Unexpected WRITE";
            break;
          case RawSocketEvent.CLOSED:
            break;
          default:
            throw "Unexpected event $event";
        }
      });
    });
}


main() {
  testDatagramBroadcastOptions();
  testDatagramMulticastOptions();
  if (!Platform.isMacOS) {
    testDatagramSocketReuseAddress();
  }
  testBroadcast();
  testLoopbackMulticast();
  testSendReceive(InternetAddress.LOOPBACK_IP_V4);
  testSendReceive(InternetAddress.LOOPBACK_IP_V6);
}
