#include "at32f403a_407.h"
#include "log_ai.h"
#include "settings_api.h"
#include "ringfs.h"
#include "ringfs_api.h"


#if defined (MAI_12)

#undef DBG
#define DBG if(1)


EventGroupHandle_t archive_event;

uint32_t archive_cnt[ARCH_AI_CH_NUMBER] = {0};

struct ringfs fs_ch_arch[ARCH_AI_CH_NUMBER];


static struct ringfs_flash_partition fingfs_flash_ch_arch[ARCH_AI_CH_NUMBER] = 
{
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*1,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*2,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*3,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*4,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*5,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*6,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*7,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*8,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*9,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*10,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    },
    {
        .sector_offset = ARCHIVE_FLASH_SECTOR_OFFSET + ARCHIVE_CHANNEL_OFFSET*11,
        .sector_erase = op_sector_erase,
        .program = op_program,
        .read = op_read,
    }
};


// Архив. 12 буферов на каждый канал.
void log_ai_archive_init(void)
{
    for (uint8_t i = 0; i < ARCH_AI_CH_NUMBER; i ++) 
    {
        fingfs_flash_ch_arch[i].sector_size = spi_flash_desc.sector_size;
        
        fingfs_flash_ch_arch[i].sector_count = ARCHIVE_FLASH_SECTOR_COUNT;
        
        ringfs_init(&fs_ch_arch[i], &fingfs_flash_ch_arch[i], 
                    ARCHIV_ENTRY_VERSION + i, sizeof(archive_entry_t));
        
        if (ringfs_scan(&fs_ch_arch[i]) != 0) {
            DBG printf("FAT for channel %u is false\r\n", i + 1);
            ringfs_format(&fs_ch_arch[i]);
        }
        DBG printf("FAT for channel %u is true\r\n", i + 1);
    }
}


//
uint8_t log_get_arch_channel_number(void)
{
    return (uint8_t)ARCH_AI_CH_NUMBER;
}


//
uint8_t log_is_channel_on(uint8_t channel)
{
    return settings.ai[channel].state;
}


//
void log_archive_task_device(void)
{
    int ret = 0;
    EventBits_t bits;
    archive_entry_t entry = {0};
    
    bits = xEventGroupWaitBits(archive_event, 
                               ARCH_CH_1 | ARCH_CH_2 | ARCH_CH_3 | ARCH_CH_4 | 
                               ARCH_CH_5 | ARCH_CH_6 | ARCH_CH_7 | ARCH_CH_8 |
                               ARCH_CH_9 | ARCH_CH_10 | ARCH_CH_11 | ARCH_CH_12,
                               pdTRUE, pdFALSE, portMAX_DELAY);
     
    for (uint32_t i = 0; i < ARCH_AI_CH_NUMBER; i++)
    {
        if (bits & (1 << i))
        {
            DBG printf("Archive event: %u\r\n", (1 << i));
                
            entry.timestamp = 0;
            //entry.input_value = di_get(i - 1);
            entry.input_value = 1;
        
            DBG printf("Append archive entry...");
            ret = log_append((void*)&entry, ARCHIVE_ENTRY, i - 1);
                
            if (ret != 0) {
                DBG printf("FAIL\r\n");
            }
            else {  
                DBG printf("OK\r\n");
            }
        }
    }
}

#endif