/*
 * logger.h
 *
 *  Created on: 26-May-2023
 *      Author: Invcuser52
 */

#ifndef LOGGER_H_
#define LOGGER_H_


#include "exo_common.h"

/* included module list */
#include "log_otsu.h"
#include "log_comms.h"
#include "log_adcs.h"
#include "log_eps.h"
#include "log_ftm.h"
#include "log_obc.h"
#include "log_tctm.h"
#include "log_scheduler.h"
#include "log_ahw.h"
#include "log_logger.h"
#include "log_error_handler.h"
#include "log_hm.h"
#include "log_ipcc.h"
#include "log_tctm.h"

#define LOG_STRING_BUFFER_MAX_LEN 50
#define SPECIFIC_MODULE_SET       1
#define ALL_LOG_SET               0
#define  READ_LOG_CONFIG          1
#define READ_LOG_HANDLE_INFO      2
#define RESPONSE_BACKUP_DATA_READ_FAIL    1
#define RESPONSE_BACKUP_ENABLE_CFG_ACK    2


// Enable this macro to test logger
//#define LOGGER_TEST



typedef enum
{
	LOG_ADCS,
	LOG_OTSU,
	LOG_COMMS,
	LOG_FTM,
	LOG_OBC,
	LOG_EPS,
	LOG_TCTM,
        LOG_SCHEDULER,
        LOG_AHW,
	LOG_LOGGER,
	LOG_ERROR_HANDLER,
        LOG_HM,
        LOG_IPCC,

	LOG_MODULE_MAX

}log_module_list;

typedef enum
{

    CONFIG_ALL_MODULE=1,
    CONFIG_SPECIFIC_MODULE,
    ALL_LOG_ALL_MODULE,
    ERROR_LOG_ALL_MODULE,
    DEFAULT_LEVEL_ALL_MODULE,
    MULTIPLE_MODULE_SET

}log_tc_command;

typedef enum
{
	LOG_ERROR       = 0x01,
	LOG_WARNING     = 0x02,
	LOG_INFO_L1		= 0x03,
	LOG_INFO_L2     = 0x04,
	LOG_INFO_L3     = 0x05,
}log_level;



typedef struct log_frame_def
{
	uint32_t module_id 			: 7;
	uint32_t enum_str_sel 		: 1;
	uint32_t enum_strlen_val 	: 16;
	uint32_t log_level 			: 4;
	uint32_t arg_cnt 			: 3;
	uint32_t reserv				: 1;
}log_frame_header;

#define LOG_TOTAL_BLOCK_CNT               1024                 /// Number of blocks to create for saving trace. It should be in multiples of 4
#define LOG_BLOCK_SIZE           		 ((uint16_t)1024)			 /// each block size in bytes


typedef struct log_storage_def
{
        uint8_t *write_addr;
        uint8_t *logger_storage_addr;
        uint8_t *tctm_log_store_addr;
        uint8_t mem_rotate_started;
        uint16_t start_block_id;
        uint16_t end_block_id;
        uint16_t current_block_id;
        uint8_t first_block_empty;
        uint8_t is_block_empty[LOG_TOTAL_BLOCK_CNT];
        uint16_t block_free_bytes[LOG_TOTAL_BLOCK_CNT];
        uint16_t bkup_erase_cycle;
}log_storage_handle;

typedef struct logger_backup
{
	uint32_t crc;             /// CRC value of partition number and index number
	uint8_t partition_no;     /// This variable indicates partition number in flash storage location
	uint8_t index_no;         ///This variable indicates index no within one partition( 8 index in one partition)
}log_backup_info;

extern uint8_t log_level_cfg[LOG_MODULE_MAX+1];




/* logger API to store data*/
void log_id(log_level level, log_module_list m_id, uint16_t enum_val);
void log_id_with_one_arg(log_level level, log_module_list m_id, uint16_t enum_val, uint32_t data);
void log_id_with_two_arg(log_level level, log_module_list m_id, uint16_t enum_val, uint32_t data1, uint32_t data2);
void log_id_with_three_arg(log_level level, log_module_list m_id, uint16_t enum_val, uint32_t data1, uint32_t data2, uint32_t data3);
void log_id_with_four_arg(log_level level, log_module_list m_id, uint16_t enum_val, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t data4);
void log_string(log_level level, log_module_list m_id, const char* string);
void log_id_with_float(log_level level, log_module_list m_id, uint16_t enum_val,float data);
void log_date(log_level level, log_module_list m_id, uint16_t enum_val, uint32_t data1, uint32_t data2, uint32_t data3,uint32_t data4);

void log_read_handler_info(log_storage_handle *ptr);

#ifndef LINUX_TEMP_PORT
uint8_t log_backup_partition_no(void);
#endif


/* logger internal functions */
void log_send_logs(uint16_t block_cnt, uint16_t mtu, uint16_t ftdsdelay, uint8_t seq_los_selection);
void log_send_logs_via_telementary(uint16_t block_cnt);
void log_backup_cfg(uint8_t cfg, uint8_t thrsld);
void log_send_backup_data(uint8_t partition_num, uint16_t mtu, uint16_t ftdsdelay, uint8_t seq_los_selection, uint8_t dwn_size);
void log_init(void);

/*This API reads logger level from NVM during logger init */
void log_level_nvm_read(void);


/* This API decodes logger TC command and pack corresponding TM data */
void log_lev_cfg_decode(uint8_t *tc_data);
/* This API read logger information like TM data */
void read_log_info(uint8_t *tc_data);
void log_backup_dwn_rsp(uint8_t *status);

#if (PERIODIC_LOG_ENB != PERIODIC_LOGGER_OFF)
/**
 * @brief This is a Logger periodic callback function, that occurs for every 10msec.
 * Used for transferring logs per block at a time
 */
void logger_periodic_timeout_cb(void* args);
#endif


#ifdef LOGGER_TEST
void log_test_func(void);
#endif

#endif /* LOGGER_H_ */
