#pragma once

#include "qsacnnode_global.h"
#include "sacn/node.h"

#include <QHash>
#include <QHostAddress>
#include <QUdpSocket>
#include <QUuid>


/**
 * @brief The QSacnNode class
 */
class QT_EXPORT QSacnNode
    : public QUdpSocket
    , public SACN::Node
{
    Q_OBJECT

public:
    explicit QSacnNode(QObject *parent = nullptr, QUuid = QUuid::createUuid());
    QSacnUniverse * universe(const uint16_t u) {return universes_.value(u); }

    // reciever
    virtual void subscribe(const uint16_t universe = 1);
    virtual void unsubscribe(const uint16_t);

signals:
    void foundUniverse(
        std::shared_ptr<SACN::EXTENDED::DISCOVERY::discoveredUniverse>);

private:
    void udpReceive();
    void emitFound(
        std::shared_ptr<SACN::EXTENDED::DISCOVERY::discoveredUniverse>);

    QHash<uint16_t, QSacnUniverse*> universes_;

public:
    // 9.3.1 Allocation of IPv4 Multicast Addresses
    // Multicast addresses are from the IPv4 Local Scope.
    static inline QHostAddress IPv4MulticastAddress(uint16_t universe) {
        quint32 address = 239 << 24 | 255 << 16 | universe;
        return QHostAddress(address);
    };
    // 9.3.2 Allocation of IPv6 Multicast Addresses
    static inline QHostAddress IPv6MulticastAddress(uint16_t universe) {
        quint8 address [] = {255, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0,
                             (quint8)(universe >> 8), (quint8)(universe & 0xff)};
        return QHostAddress(address);
    };
};

