#include "log_api.h"
#include "log.h"
#include "rtc.h"
#include "ringfs.h"
#include "spi_flash.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "rtc.h"
#include <string.h>
#include <stdio.h>
#include <inttypes.h>

#undef DBG
#define DBG if(1)

extern struct ringfs fs_log;
extern struct ringfs fs_ch_arch[];

extern SemaphoreHandle_t log_mutex;

static archive_entry_t archive_entry;
static log_entry_t log_entry;



//
int log_get_archive_entry(uint32_t index, struct ringfs *fs, void *entry)
{
    archive_entry_t *ent = entry;
    
	int start = ringfs_count_estimate(fs);
    
    fs->cursor_position =  start - (index - 1) - 1;
    
	if (fs->cursor_position < 0)
		return -1;
	else
    {
		fs->cursor.sector = (fs->read.sector + fs->cursor_position/fs->slots_per_sector)%fs->flash->sector_count;
		fs->cursor.slot = fs->cursor_position%fs->slots_per_sector;
	}
    
    log_fetch(entry, ARCHIVE_ENTRY, 0, portMAX_DELAY);
#if 0
    printf("[archive entry] timestamp = % " PRId64 ", value = %u, crc = %u\r\n", 
           ent->timestamp, ent->input_value, ent->crc);
#endif    
    return 0;
}

//
int log_get_log_entry(uint32_t index, struct ringfs *fs, void *entry)
{
    log_entry_t *ent = entry;
    
    int start = ringfs_count_estimate(fs);
    
    fs->cursor_position =  start - (index - 1) - 1;
    
	if (fs->cursor_position < 0)
		return -1;
	else
    {
		fs->cursor.sector = (fs->read.sector + fs->cursor_position/fs->slots_per_sector)%fs->flash->sector_count;
		fs->cursor.slot = fs->cursor_position%fs->slots_per_sector;
	}
    
    log_fetch(entry, LOG_ENTRY, 0, portMAX_DELAY);
   
#if 0
/*
    printf("[log entry] timestamp = % " PRId64 ", code_type = %u, code_state = %u, \
           channel_number = %u, value = %f, crc = %u\r\n", ent->timestamp, \
           ent->code_type, ent->code_state, ent->channel_number, ent->value, ent->crc);
*/    
    printf("[log entry] timestamp = % " PRId64 ", code_type = %u",
           ent->timestamp, ent->code_type);
    
    printf(" code_state = %u, channel_number = %u", ent->code_state, ent->channel_number);
    
    printf(" value = %f, crc = %u\r\n", ent->value, ent->crc);
    
#endif    
    return 0;
}

//
int mb_archive_get_entry(uint8_t *buf, uint8_t ch, uint16_t entry_index)
{
    uint8_t pack_len = 3;
    buf[2] = MB_ARCHIVE_ENTRY;  // Reference type

#if defined (MDIO_88) || (MAI_12)       
    if (log_get_archive_entry(entry_index, &fs_ch_arch[ch], &archive_entry) == -1)
        return 0;
#endif
    
#if 0    
    printf("[entry] timestamp = % " PRId64 ", value = %u, crc = %u\r\n", 
           archive_entry.timestamp, archive_entry.input_value, archive_entry.crc);
#endif
    
    memcpy(&buf[3], &archive_entry, sizeof(archive_entry_t));
    pack_len += sizeof(archive_entry_t);
    
    buf[0] = pack_len; // Resp. data length, 1 byte
    buf[1] = pack_len; // File Resp. length, 1 byte
    
    return pack_len;
}

//
int mb_log_get_entry(uint8_t *buf, uint16_t entry_index)
{
    uint8_t pack_len = 3;
    buf[2] = MB_LOG_ENTRY;  // Reference type
    
    log_get_log_entry(entry_index, &fs_log, &log_entry);
    memcpy(&buf[3], &log_entry, sizeof(log_entry_t));
    pack_len += sizeof(log_entry_t);
    
    buf[0] = pack_len; // Resp. data length, 1 byte
    buf[1] = pack_len; // File Resp. length, 1 byte
    
    return pack_len;
}


