// Credits: asivery/rm-xovi-extensions 
// (https://github.com/asivery/rm-xovi-extensions/blob/master/xovi-message-broker/src/XoviMessageBroker.h)

#import <Foundation/Foundation.h>
#include "MessageBroker.h"
#include "Logger.h"
#include <vector>
#include <cstring>
#include <algorithm>

static std::vector<MessageBroker *> brokers;
static NativeSignalCallback nativeCallback = nullptr;

void messagebroker::setNativeCallback(NativeSignalCallback callback) {
    nativeCallback = callback;
    NSLogger(@"[MessageBroker] Native callback registered");
}

void messagebroker::addBroadcastListener(MessageBroker *ref) {
    // Cannot have more than one.
    if(std::find(brokers.begin(), brokers.end(), ref) == brokers.end()) {
        brokers.push_back(ref);
        NSLogger(@"[MessageBroker] Added broadcast listener, total: %zu", brokers.size());
    }
}

void messagebroker::removeBroadcastListener(MessageBroker *ref) {
    std::vector<MessageBroker *>::iterator iter;
    if((iter = std::find(brokers.begin(), brokers.end(), ref)) != brokers.end()) {
        brokers.erase(iter);
        NSLogger(@"[MessageBroker] Removed broadcast listener, remaining: %zu", brokers.size());
    }
}

void messagebroker::broadcast(const char *signal, const char *value) {
    QString qSignal(signal), qValue(value);
    NSLogger(@"[MessageBroker] Broadcasting signal '%s' with value '%s'", signal, value);
    
    // Call native C++ callback if registered
    if (nativeCallback) {
        nativeCallback(signal, value);
    }
    
    // Notify QML listeners
    for(auto &ref : brokers) {
        if(ref->getListeningFor().contains(qSignal)) {
            emit ref->signalReceived(qSignal, qValue);
        }
    }
}

void messagebroker::registerQmlType() {
    qmlRegisterType<MessageBroker>("net.noham.MessageBroker", 1, 0, "MessageBroker");
    NSLogger(@"[MessageBroker] Registered QML type net.noham.MessageBroker");
}

// Include MOC output for MessageBroker class (generated by Qt's Meta-Object Compiler)
#include "moc_MessageBroker.cpp"