#include <stdint.h>
#include <stdbool.h>

#include <config.h>
#include <eeprom.h>
#include <logger.h>
#include <mbusComm.h>



#define NUM_OF_DEFAULT_DEVICES 8
t_deviceBlock defaultDeviceBlock[] = {
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Total",
        .address = 80,
        .consideredField = { 0, 17, -1, -1 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Computer",
        .address = 85,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Dryer",
        .address = 81,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Laundry",
        .address = 82,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Dishwasher",
        .address = 83,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Light",
        .address = 84,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Freezer",
        .address = 86,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    },
    {
        .deviceMagic = DEVICE_MAGIC,
        .deviceName = "Fridge",
        .address = 87,
        .consideredField = { 0, 4, 2, 3 },
        .period = 10,
        .filler = { 0, 0, 0 }
    }
};


t_configBlock defaultConfigBlock = {
    .configMagic = CONFIG_MAGIC,
    .deviceName = "MBGW3",
    .macAddress = { 0x00, 0xA0, 0x57, 0x05, 0x3E, 0x0D },
    .frontendThreshold = 240,
    .brokerName = "mqttbroker",
    .watchdogTopic = "IoT/Watchdog",
    .startupTopic = "IoT/MBGW3/Startup",
    .statusTopic = "IoT/MBGW3/Status",
    .mbusDataTopic = "IoT/MBGW3/Measurement",
    .syslogServerName = "syslogserver",
    .numOfDeviceBlocks = NUM_OF_DEFAULT_DEVICES,
    .filler = { 0 }
};



t_configBlock mainConfigBlock;



t_configBlock* getConfig() {
    return &mainConfigBlock;
}


void configInit() {
    coloredMsg(LOG_BLUE, false, "cfg ci Reading configuration block from eeprom");
    eepromReadConfigBlock(&mainConfigBlock);

    if (mainConfigBlock.configMagic != CONFIG_MAGIC) {
        coloredMsg(LOG_BLUE, false, "cfg ci Invalid configuration block read from eeprom");

        eepromWriteConfigBlock(&defaultConfigBlock);
        coloredMsg(LOG_BLUE, false, "cfg ci Default configuration block written to eeprom");

        for (uint8_t i = 0; i < NUM_OF_DEFAULT_DEVICES; i++) {
            eepromWriteDeviceBlock(i, &defaultDeviceBlock[i]);
        }
        coloredMsg(LOG_BLUE, false, "cfg ci Default device blocks written to eeprom");

        coloredMsg(LOG_BLUE, false, "cfg ci Reading configuration block from eeprom again");
        eepromReadConfigBlock(&mainConfigBlock);
    }
    coloredMsg(LOG_BLUE, false, "cfg ci configMagic:         %lx", mainConfigBlock.configMagic);
    coloredMsg(LOG_BLUE, false, "cfg ci deviceName:          %s", mainConfigBlock.deviceName);
    coloredMsg(LOG_BLUE, false, "cfg ci MAC address:         %02x:%02x:%02x:%02x:%02x:%02x", mainConfigBlock.macAddress[0], 
                                                                                      mainConfigBlock.macAddress[1], 
                                                                                      mainConfigBlock.macAddress[2], 
                                                                                      mainConfigBlock.macAddress[3], 
                                                                                      mainConfigBlock.macAddress[4], 
                                                                                      mainConfigBlock.macAddress[5]);
    coloredMsg(LOG_BLUE, false, "cfg ci frontend threshold:  %ld", mainConfigBlock.frontendThreshold);
    coloredMsg(LOG_BLUE, false, "cfg ci broker:              %s", mainConfigBlock.brokerName);
    coloredMsg(LOG_BLUE, false, "cfg ci watchdogTopic:       %s", mainConfigBlock.watchdogTopic);
    coloredMsg(LOG_BLUE, false, "cfg ci startupTopic:        %s", mainConfigBlock.startupTopic);
    coloredMsg(LOG_BLUE, false, "cfg ci statusTopic:         %s", mainConfigBlock.statusTopic);
    coloredMsg(LOG_BLUE, false, "cfg ci mbusDataTopic:       %s", mainConfigBlock.mbusDataTopic);
    coloredMsg(LOG_BLUE, false, "cfg ci syslog server:       %s", mainConfigBlock.syslogServerName);
    coloredMsg(LOG_BLUE, false, "cfg ci device block cnt:    %d", mainConfigBlock.numOfDeviceBlocks);

    for (uint8_t i = 0; i < mainConfigBlock.numOfDeviceBlocks; i++) {
        t_deviceBlock tmpDeviceBlock;
        eepromReadDeviceBlock(i, &tmpDeviceBlock);
        if (tmpDeviceBlock.deviceMagic == DEVICE_MAGIC) {
            coloredMsg(LOG_BLUE, false, "cfg ci device %d: ", i);
            coloredMsg(LOG_BLUE, false, "  Name: %s, Address: %d, Period: %d", 
                       tmpDeviceBlock.deviceName, tmpDeviceBlock.address, tmpDeviceBlock.period);
            coloredMsg(LOG_BLUE, false, "  Considered Fields: %d %d %d %d",
                       tmpDeviceBlock.consideredField[0],
                       tmpDeviceBlock.consideredField[1],
                       tmpDeviceBlock.consideredField[2],
                       tmpDeviceBlock.consideredField[3]);
            mbusCommAddDevice(&tmpDeviceBlock);
        } else {
            coloredMsg(LOG_BLUE, false, "magic of device %d does not match, ignored", i);
        }
    }
}