#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <uuid/uuid.h>

#include <logger.h>
#include <models/controller.h>
#include <handlers.h>
#include <drivers.h>
#include <enums.h>
#include <helpers.h>
#include <wiringPi.h>
#include <wiring_debug.h>

void
handler_loop(struct mg_connection *c_mqtt)
{
    char topic_buf[100];
    char payload_buf[2];
    char controller_uid[UUID_STR_LEN];
    uuid_unparse(global_controller->id, controller_uid);

    time_t timestamp = time(NULL);
    struct tm *time_struct = localtime(&timestamp);
    LOG_DEBUG("===== IDLE LOOP START =====\n");
    for(uint_fast8_t i = 0; i < global_controller->relay_count; ++i)
    {
        relay_t *relay = global_controller->relays[i];
        int is_active = 0;
        if(relay_is_active(relay, time_struct))
        {
            LOG_DEBUG("relay %d is active\n", i);
            is_active = 1;
        }

        if(relay->is_on != is_active)
        {
            relay->sent_to_broker = 0;
        }
        if(!relay->sent_to_broker && c_mqtt)
        {
            sprintf(topic_buf, "controller/%s/relay/%u", controller_uid, i);
            sprintf(payload_buf, "%u", is_active);
            mg_mqtt_publish(c_mqtt, topic_buf, 0, MG_MQTT_QOS(0), payload_buf, strlen(payload_buf));
            relay->sent_to_broker = 1;
        }
        relay->is_on = is_active;

        if(global_config.relay_configs[i].inverted)
        {
            is_active = !is_active;
        }
        switch(global_config.relay_configs[i].driver)
        {
            case RELAY_DRIVER_GPIO:
                driver_gpio_set(global_config.relay_configs[i].pin, is_active);
                break;
            case RELAY_DRIVER_PIFACE:
                driver_piface_set(global_config.relay_configs[i].pin, is_active);
                break;
            default:
                LOG_WARN("relay %d is not using a driver\n", i);
        }
    }
}