#include <qthing.h>
#include "event.h"

string_callback_t log_oled_callback = NULL;
void set_oled_log_callback(string_callback_t callback) {
    log_oled_callback = callback;
}
void log_oled(const std::string& message) {
    if (log_oled_callback != NULL) {
        log_oled_callback(message);
    }
}

volatile connection_status_t wlan_connection_status = uninitialized;
connection_status_callback_t wlan_connection_status_callback = NULL;
void add_wlan_connection_status_callback(connection_status_callback_t callback) {
    if (wlan_connection_status_callback == NULL) {
        wlan_connection_status_callback = callback;
    }
    else {
        connection_status_callback_t old_callback = wlan_connection_status_callback;
        wlan_connection_status_callback = [old_callback, callback](connection_status_t status){
            old_callback(status);
            callback(status);
        };
    }
}
void update_wlan_connection_status(connection_status_t status) {
    wlan_connection_status = status;
    if (wlan_connection_status_callback != NULL) {
        wlan_connection_status_callback(status);
    }
}
connection_status_t get_wlan_connection_status() {
    return wlan_connection_status;
}

volatile connection_status_t mqtt_connection_status = uninitialized;
connection_status_callback_t mqtt_connection_status_callback = NULL;
void add_mqtt_connection_status_callback(connection_status_callback_t callback) {
    if (mqtt_connection_status_callback == NULL) {
        mqtt_connection_status_callback = callback;
    }
    else {
        connection_status_callback_t old_callback = mqtt_connection_status_callback;
        mqtt_connection_status_callback = [old_callback, callback](connection_status_t status){
            old_callback(status);
            callback(status);
        };
    }
}
void update_mqtt_connection_status(connection_status_t status) {
    mqtt_connection_status = status;
    if (mqtt_connection_status_callback != NULL) {
        mqtt_connection_status_callback(status);
    }
}
connection_status_t get_mqtt_connection_status() {
    return mqtt_connection_status;
}

connection_status_callback_t combined_mqtt_connection_status_callback = NULL;
void update_combined_mqtt_connection_status() {
    connection_status_t status = uninitialized;
    if (wlan_connection_status == uninitialized) {
        status = uninitialized;
    }
    else if (wlan_connection_status == disconnected) {
        status = disconnected;
    }
    else if (wlan_connection_status == connecting || mqtt_connection_status == connecting) {
        status = connecting;
    }
    else if (mqtt_connection_status == disconnected) {
        status = disconnected;
    }
    else if (wlan_connection_status == connected && mqtt_connection_status == connected) {
        status = connected;
    }
    combined_mqtt_connection_status_callback(status);
}
void add_combined_mqtt_connection_status_callback(connection_status_callback_t callback) {
    if (combined_mqtt_connection_status_callback == NULL) {
        combined_mqtt_connection_status_callback = callback;
        add_wlan_connection_status_callback([](connection_status_t wlan_status){
            update_combined_mqtt_connection_status();
        });
        add_mqtt_connection_status_callback([](connection_status_t mqtt_status){
            update_combined_mqtt_connection_status();
        });
    }
    else {
        connection_status_callback_t old_callback = combined_mqtt_connection_status_callback;
        combined_mqtt_connection_status_callback = [old_callback, callback](connection_status_t status){
            old_callback(status);
            callback(status);
        };
    }
}
bool is_mqtt_connected() {
    return wlan_connection_status == connected && mqtt_connection_status == connected;
}