#ifndef __LOG_H
#define __LOG_H

#include "at32f403a_407.h"
#include <stdbool.h>


#define LOG_ENTRY_VERSION               1

#define ARCHIV_ENTRY_VERSION            1

#define LOG_FLASH_SECTOR_OFFSET         4

#define LOG_FLASH_SECTOR_COUNT          252

#define ARCHIVE_FLASH_SECTOR_OFFSET     260

#define ARCHIVE_FLASH_SECTOR_COUNT      252

#define SECTOR_COUNT (spi_flash_desc.sector_count/2 - LOG_FLASH_SECTOR_OFFSET)


//
typedef enum 
{
    LOG_SYSTEM_BOOT = 0,			// device booted
    LOG_SYSTEM_DEFCONFIG,	// default config applied
    LOG_UPDATE_SOFT,
    LOG_TURN_ON,		//
    LOG_PSW_CHANGE,		//
    LOG_SETTING_SAVE,		//
    LOG_LOGIN_TELNET,		//
    LOG_LOGIN_SSH,
    LOG_LOGIN,		//
    LOG_TEST_UPS,		//
    LOG_SHUTDOWN_UPS,
    LOG_ALARM_VAC_LOW_OUTPUT,
    LOG_ALARM_VAC_HIGH_OUTPUT,
    LOG_ALARM_HIGH_TEMP,
    LOG_ALARM_LOW_TEMP,
    LOG_ALARM_LINE,
    LOG_ALARM_LOW_BAT,
    LOG_ALARM_POWER,
    LOG_ALARM_UPS,
    LOG_ALARM_AKB,
    LOG_ALARM_CHANGE_AKB,
    LOG_PHASE_FAIL,
    LOG_EPO_FAIL,
    LOG_VALUE,
    LOG_NONE,
} log_type_t;


typedef enum
{
    LOG_ENTRY = 0,
    ARCHIVE_ENTRY,
    
} entry_type_t;


typedef __packed struct 
{
    uint64_t timestamp;
    
} common_entry_t;

//
typedef __packed struct 
{
	uint64_t timestamp;
	log_type_t type:8;
	char data[50];
    uint8_t crc;
    
} log_entry_t;


typedef __packed struct
{
    uint64_t timestamp;
    uint8_t input_value;
    uint8_t crc;
} archive_entry_t;


//
void log_init(bool format);

//
int log_fetch(void *entry, entry_type_t entry_type, uint32_t timeout);

//
int log_discard(void *entry, entry_type_t entry_type, uint32_t timeout);

// 
int log_append(void *entry, entry_type_t entry_type);


// -------------------------------------------------------------------------- //
// misc

uint8_t crc_8(uint8_t *data, int length);

// -------------------------------------------------------------------------- //
// Tests

// fs_log
int log_test(void);

// fs_archive
int test_archive(void);

//
int test_add_random_archive_entry(uint32_t cnt_entry);

//
void test_archive_info(void);

//
void test_fetch(void);

//
void test_archive_format(void);


#if 0

#include "main.h"
#include "common_config.h"

#define FILE_BUF_MAX_LEN            10*STRING_SIZE_HISTORY // Размер временного буфера для отправки/копирования Лог файла
#define FILE_BUF_MAX_LEN_LOG        10*STRING_SIZE // Размер временного буфера для отправки/копирования Лог файла
#define STRING_SIZE                 64
#define STRING_SIZE_HISTORY		  	100
#define UPS_DATA_STRING_SIZE        47

extern char logFileBuf[FILE_BUF_MAX_LEN];

extern char name_login[50];


#define LOG_ENTRY_VERSION 1

extern void log_init(bool format);
extern int log_test(void);
extern int log_append(log_entry_t *entry);
extern int log_fetch(log_entry_t *entry, uint32_t timeout);
extern int log_rewind(log_entry_t *entry, uint32_t timeout);
extern int log_discard(log_entry_t *entry, uint32_t timeout);

void log_add(char *log_data);
void log_event_data(log_type_t type, char *data);

/**
  * @brief  Возвращает true если журнал проинициализирован
  */
bool LOG_IsInit();

/**
  * @brief  Отключает журнал для безопасной перезагрузки
  */
bool LOG_Disable(void);

/**
  * @brief  Возвращает общее количество страниц
  */
uint32_t LOG_GetPageCount(void);
uint32_t LOG_GetTotalSTRCount(void);
void LOG_GetPage(char *str, uint32_t page);
void LOG_GetPage_tabs(char *str, uint32_t page);
uint32_t LOG_GetData(int ptr, char *str, uint32_t size, bool start);

uint32_t History_GetPageCount(void);
uint32_t History_GetTotalSTRCount(void);
void History_GetPage(char *str, uint32_t page);
uint32_t History_GetData(int ptr, char *str, uint32_t size, bool start);
void History_GetPage_tabs(char *str, uint32_t page);

#endif

#endif /* __LOG_H */
