#ifndef _EXO_COMMON_H_
#define _EXO_COMMON_H_
#include "stdint.h"

#include "exo_debug.h"

#define _UNUSED_(x) (void)(x)

#ifdef ENABLE_CPRINT
#define DEBUG_CPRINT(x) do {printf x;} while(0)
#define CPRINT_VARIABLE_UNUSED(x)
#else
#define DEBUG_CPRINT(message)
#define CPRINT_VARIABLE_UNUSED(x) (void)(x)
#endif
#ifndef LINUX_TEMP_PORT
#define mallocASSERT( x ) if((x) == NULL) {EXO_ASSERT(RTOS_ASSERT);}
#else
#define mallocASSERT( x ) if((x) == NULL) {abort();}
#endif


#define T_STACK_1K  ( 1*1024)
#define T_STACK_2K  ( 2*1024)
#define T_STACK_3K  ( 3*1024)
#define T_STACK_4K  ( 4*1024)
#define T_STACK_5K  ( 5*1024)
#define T_STACK_8K  ( 8*1024)
#define T_STACK_10K (10*1024)
#define T_STACK_1P5K ( 1536)
#define T_STACK_2P5K ( 2560)

#define T_MAIN_STACK_SIZE  			( 512)
#define T_OSAL_TEST_STACK_SIZE  		( 512)

#define T_OS_TIMER_STACK_SIZE   		(T_STACK_3K / 4)
#define T_SDR_APP_STACK_SIZE   			T_STACK_5K
#define T_COMMS_RX_STACK_SIZE			T_STACK_5K
#define T_COMMS_SBAND_TX_STACK_SIZE			T_STACK_8K
#define T_COMMS_UHF_TX_STACK_SIZE			T_STACK_5K
#define T_COMMS_UHF_STACK_SIZE   		T_STACK_5K
#define T_XBAND_STACK_SIZE 			T_STACK_5K
#define T_OBC_MEM_DEBUG_STACK_SIZE    		T_STACK_1K
#define T_LOG_THREAD_STACK_SIZE   		1024
#define T_OSAL_MEM_STACK_SIZE     		1536
#define T_SENSOR_STACK_SIZE    			T_STACK_5K
#define T_HAL_INTR_SIZE      			T_STACK_5K
#define T_TCTM_IPC_SEND_STACK_SIZE    		T_STACK_5K
#define T_TCTM_IPC_RECIEVE_STACK_SIZE    	T_STACK_5K
#define T_TCTM_STORAGE_STACK_SIZE    		T_STACK_5K
#define T_TEST_TASK_STACK_SIZE                  T_STACK_2K
#define T_OBC_IPCC_RECEIVE_STACK_SIZE    	T_STACK_5K
#define T_OBC_IPCC_SEND_STACK_SIZE  		T_STACK_5K
#define T_OBC_MAIN_STACK_SIZE  			T_STACK_5K
#define T_FTM_FSM_HANDLER_STACK_SIZE  		1536
#define T_FTM_TCTM_RCV_STACK_SIZE  		2048
#define T_FTM_TCTM_SEND_STACK_SIZE 		1536
#define T_ADCS_CSW_STACK_SIZE    		T_STACK_10K
#define T_ADCS_EVNT_HNDLR_STACK_SIZE    	T_STACK_8K
#define T_EPS_STACK_SIZE    			T_STACK_5K
#define T_SCH_STACK_SIZE    			T_STACK_8K
#define T_COMMS_STACK_SIZE   			T_STACK_10K
#define T_OBC_OTSU_STACK_SIZE 			T_STACK_5K
#define T_LOGGER_TRACE_STACK_SIZE  		1536
#define T_COMMS_IQ_STACK_SIZE T_STACK_5K
#define T_ERR_HANLDER_STACK_SIZE  		3096
#define T_GPS_TASK_STACK_SIZE   T_STACK_4K
#define T_HM_IPC_RECIEVE_STACK_SIZE             T_STACK_5K
#define T_THRUSTER_STACK_SIZE   T_STACK_4K

#define RTC_HR    4
#define RTC_MIN   6
#define RTC_SEC   0
#define RTC_DATE  10
#define RTC_MON   (2 - 1)  // Do not remove -1 
#define RTC_YEAR  (2023 - 1900) // Do not remove 1900

#define EXT_SDRAM_BUFF_USB_ENB
#define EXT_SDRAM_BUFF_ETH_ENB
#define EXT_SDRAM_BUFF_SENSOR_ENB
#define EXT_SDRAM_BUFF_EPS_ENB

#define LWIP_RESET_CNT_THRES (10)

//#define SBAND_BEACON_ENB

#ifndef UNUSED
#define UNUSED(X) (void)X
#endif

#define DEFAULT_RADIO_ID (0)

#define TC_RADIO_MOD_IDX        2
#define TC_PLD_IDX              3

#define TM_SEQ_IDX              0
#define TM_CTRL_DATA_IDX        2
#define TM_RADIO_MOD_IDX        3
#define TM_PLD_IDX              4

#define TM_DEFAULT_CTRL_DATA    0x70

#define TM_HEADER_OVERHEAD         (128)

#define TC_DEFERRED_STORAGE_LENGTH  (2*1024*1024)

#define MAX_TCTM_DBG_INFO 16
#define DEFAULT_COMMS_RADIO_ID 0xFF
/**
 * @brief Global structure for debug control block
 *
 */

/*MACRO defined to check whether the NVM value is within range*/

#define RANGE_CHECK_AND_ASSIGN(value,min,max,def_val) \
    ((value>=min)&&(value<=max))?value:def_val
    



/*Structure including control variable for TCTM manager*/
typedef struct
{
    uint32_t tm_manager_ipc_rcvd;     //Increments on every IPC receive
    uint32_t tc_sent_to_obc_succ;     //Increments on successful TC sent to OBC
    uint32_t tc_sent_to_obc_fail;     //Increments on failure of TC sent to OBC
    uint32_t tm_sent_to_comms_succ;   //Increments on successful TM sent to comms
    uint32_t tm_sent_to_comms_fail;   //Increments on failure of TM sent to comms
    uint32_t grd_contact_strt_ind;    //Increments on every ground contact
    uint32_t grd_contact_stop_ind;    //Increments on every ground contact loss
    uint32_t tc_extract_succ;         //Increments on Successful TC extract
    uint32_t tc_unpack_succ;          //Increments on Successful TC unpackt
    uint32_t tc_data_not_null;        //Increments on TC Data not a NULL
    uint32_t tc_tm_sts_fail;          //Increments on TC extract, decryption fail

}__attribute__((__packed__))tc_tm_dbg_cb;

/*Structure including control variable for Comms */
typedef struct
{
    uint32_t csp_comms_rcvd;        //Increments on every packet received in csp comms
    uint32_t csp_comms_sent;        //Increments on every packet sent in csp comms
    uint32_t csp_sltcp_rcvd;        //Increments on every packet received in csp-sltcp
    uint32_t csp_sludp_rcvd;        //Increments on every packer received in csp-sludp

}__attribute__((__packed__))comms_dbg_cb;


/*Structure including control variable for IPCC  */
typedef struct
{
    uint32_t no_ipcc_rsp_sent;       //Increments on every response sent to PS
    uint32_t ipcc_rcv_succ;          //Increments on every successful IPCC receive
    uint32_t ipcc_rcv_fail;          //Increments on every failure of IPCC receive
    uint32_t ipcc_cmd_ntf_req_sent;  /*Increments on every command or notification  
                                                        or request sent*/

}__attribute__((__packed__))ipcc_dbg_cb;


/*Structure including control variable for Health metric */
typedef struct
{
    uint32_t no_ipc_rcvd;            //Increments on every IPC received
    uint32_t buffer_req;             //Increments on every buffer request
    uint32_t enqueue_req;            //Increments on every enqueue request
    uint32_t dl_req;                 //Increments on every dl request
    uint32_t flush_req;              //Increments on every flush request
    uint32_t del_queue_req;          //Increments on every queue delete request
    uint32_t queue_pri_chnge_req;    //Increments on every queue priority change request
    uint32_t mod_pri_chnge_req;      //Increments on every module priority change request
    uint32_t no_rsp_ipc_sent;        //Increments on every response IPC sent
    uint32_t hm_tm_ipc_sent;          //Increments on every IPC sent from HM to COMMS

}__attribute__((__packed__))hm_dbg_cb;

/**
 * @brief Structure contains the received telecommand informations 
 */
typedef struct
{
    uint32_t tc_rcvd_time;          /*!< TC received time */
    uint16_t tc_id;                 /*!< TC Id */
    uint16_t dst_id;                /*!< Destination Id */
}__attribute__((__packed__))s_tc_dbg_info;

/**
 * @brief Structure contains the received telemetry informations
 */
typedef struct
{
    uint32_t tm_sent_time;          /*!< TM Sent/generated time */
    uint16_t tm_id;                 /*!< TM Id */
    uint16_t src_id;                /*!< Source Id */
}__attribute__((__packed__))s_tm_dbg_info;

/**
 * @brief task ID enumeration
 */
typedef enum
{
    OS_TIMER,
    CSP_TASK,
    CSP_TASK1,
    CSP_TASK2,
    CSP_TASK3,
    CSP_ETH_RX,
    ETHERNET_TASK,
    USB_TASK,
    UART_EDGE_CONTROLLER,
    EPS_TASK,
    LWIP_MBOX_TASK,
    LWIP_TASK,
    SDR_APP,
    COMMS_RX,
    COMMS_SBAND_CTLR,
    COMMS_UHF_CTLR,
    COMMS_SBAND_IQ,
    COMMS_SBAND_TX,
    COMMS_UHF_TX,
    COMMS_XBAND_CTLR,
    ORBIT_CONOPS_SCHEDULER,
    ADCS_SERVER_THREAD,
    ADCS_CONTROLLER,
    ADCS_EVENT_THREAD,
    TC_TM_MANAGER_IPC_RECEIVE,
    TC_TM_MANAGER_IPC_SEND,
    TM_STORAGE,
    OBC_MAIN,
    FTM_FSM_HANDLER,
    FTM_TCTM_RCV,
    FTM_TCTM_SEND,
    OBC_IPCC_RECEIVE,
    OBC_IPCC_SEND,
    IO_THREAD,
    OBC_OTSU,
    OBC_MEMCPY_THREAD,
    DEBUG_LOGGER,
    LOGGER_TRACE,
    ERR_HANDLER,
    HM_MANAGER_IPC_RECEIVE,
#if defined(TEST_LAYER) 
    TEST_TASK,
#endif
    IDLE_TASK,
    OBC_MEM_DEBUG_TC,
    OBC_SENSOR_HDLR,
    HAL_INTR_HDLR,
    PLD_SRV_TASK,
    GPS_TASK,
#if 0
    THREAD_TX_1,
    THREAD_TX_2,
    THREAD_TX_3,
    THREAD_TX_4,
#endif

    SPI_TO_UART_RCV_TASK,
    SPI_TO_UART_TRANS_TASK,
    SPI_TO_UART_CALLBACK_TASK,

#ifdef LINUX_TEMP_PORT
    OBC_SNS_SIMU,
    THRUSTER_SIMU,
#endif
#ifdef EPS_SIMU_ENABLE
    OBC_EPS_SIMU,
#endif

#if (PERIODIC_LOG_ENB == 1) || defined(ENABLE_SOC_PRINT)
    OBC_LOGGER_SOCKET,
#endif
   
    //EPS_TC_TM_CONTROLLER,
#ifdef LWIP_THROW_TEST
	TEST_SOC_UDP,
#endif
    OS_TASK_MAX

}e_exo_task_id;

/*Structure including control variable for OBC */
typedef struct
{
    uint32_t obc_main_ipc_rcvd;      //Increments on every IPC receive
    uint32_t no_tc_rcvd;             //Increments on every TC received
    uint32_t no_tm_pakd;             //Incements when every TM packed
    uint32_t obc_main_ipc_sent;      //Increments on every IPC sent
    uint16_t ipc_fail_queue_full_cntr[OS_TASK_MAX];    //Increments on every IPC fail in queue full scenario

}__attribute__((__packed__))obc_dbg_cb;

typedef struct
{
    tc_tm_dbg_cb tc_tm_dbg;
    obc_dbg_cb obc_dbg;
    comms_dbg_cb comms_dbg;
    ipcc_dbg_cb ipcc_dbg;
    hm_dbg_cb hm_dbg;
}__attribute__((__packed__))exo_sw_dbg_cb;

/**
 * @brief task priority enumeration*/
typedef enum
{
    P_IDLE                     = 1,
#if defined(TEST_LAYER) 
    P_TASK_TEST                   ,
#endif
    P_DEBUG_LOGGER                ,
    P_LOGGER_TRACE                ,
    P_OBC_MEMCPY_THREAD	          ,
    P_OBC_TC_DECODE               ,
    P_OBC_OTSU                    ,
    P_IO_THREAD                   ,
    P_DEFAULT_PRIO              =10,
    P_ERR_HANDLER                 ,
    P_GPS_TASK                    ,
    P_COMMS_XBAND_CTLR            ,
    P_OBC_IPCC_SEND               ,
    P_OBC_IPCC_RECEIVE            ,
    P_FTM_TCTM_SEND               ,
    P_FTM_TCTM_RCV               ,
    P_FTM_FSM_HANDLER             ,
    P_ORBIT_CONOPS_SCHEDULER      ,
    P_OBC_SENSOR_HDLR             ,
    P_HM_MANAGER_IPC_RECEIVE      ,
#ifdef LINUX_TEMP_PORT
    P_OBC_SENSOR_SIMU             ,
    P_THRUSTER_SIMU             ,
#endif
#ifdef EPS_SIMU_ENABLE
    P_OBC_EPS_SIMU                ,
#endif

#if (PERIODIC_LOG_ENB == 1) || defined(ENABLE_SOC_PRINT)
    P_OBC_LOGGER_SOCKET           ,
#endif    
    P_OBC_MAIN                    ,
    P_TM_STORAGE,
    P_TC_TM_MANAGER_IPC_SEND      ,
    P_TC_TM_MANAGER_IPC_RECEIVE   ,
    P_SDR_APP                     ,
    P_COMMS_UHF_CTLR            ,
    P_COMMS_UHF_TX              ,
    P_COMMS_UHF_RX              ,
    P_ADCS_SERVER                 ,
    P_ADCS_CONTROLLER             ,
    P_ADCS_EVENT_HDLR             ,
    P_COMMS_SBAND_CTLR            ,
    P_COMMS_SBAND_IQ            ,
    P_COMMS_SBAND_TX              ,
    P_COMMS_RX              ,
    P_EPS                         ,
    P_UART_EDGE_CONTROLLER        ,
#ifdef LWIP_THROW_TEST
    P_TEST_SOC                    ,
#endif
    P_LWIP                        ,
    P_LWIP_MBOX                   ,
    P_CSP_ROUTE                   ,
    P_USB                         ,
    P_CSP_INTF_UART_RX            ,
    P_CSP_INTF_CAN_RX             ,
    P_CSP_INTF_ETH_RX             ,
    P_UART_RX                     ,
    P_HAL_INTR_HDLR               ,
    P_ETHERNET                    ,
    P_OS_TIMER                    ,
#if 0

    P_THREAD_TX_1,
    P_THREAD_TX_2,
    P_THREAD_TX_3,
    P_THREAD_TX_4,
#endif
    P_SPI_TO_UART_CONV_CALLBACK	  ,
    P_SPI_TO_UART_CONV_TX		  ,
    P_SPI_TO_UART_CONV_RX		  ,


    P_OS_TASK_MAX

}e_exo_task_priority;


typedef enum
{
    PWR_OFF 	= 0,
    PWR_ON		= 1,
    PWR_RSTRT	= 2,
    PWR_BOOT	= 3,
    PWR_SD		= 4,
    PWR_ERR
}dev_hw_sts_s;

//socket details
typedef struct obc_sock_info
{
    char ip_addr[16];
    unsigned short port;
}s_obc_sock_info;

typedef enum dev_sw_st
{
    SW_INACTIVE = 0,
    SW_ACTIVE = 1,
    SW_ERROR = 2
}dev_sw_sts_s;

typedef enum
{
    //	HW_BTRY_OFF = 0,
    HW_BTRY_CRTCAL = 0,
    HW_BTRY_SAFE,
    HW_BTRY_NORMAL,
    //  HW_BTRY_FULL
}sat_btry_sts_s;


typedef struct _btry_info
{
    sat_btry_sts_s status;
    float volt;
}sat_btry_info_s;

#if JANUS1

typedef enum hw_ch
{
    HW_PL_TRANSCELESTIAL = 0,
    HW_X_BAND,
    HW_S_BAND,
    HW_ADCS0,
    HW_ADCS,
    HW_PROP_UNIT_THRUSTER,
    HW_PL_ZES,
    HW_PL_SAYARLABS,
    HW_PL_NETRA,
    HW_EDGE_BRD,
    HW_OBC_PS_GPS_STD_PL_BRD,
    HW_HRM,
    HW_PL_SERVER,
    HW_GPS,
    HW_UHF,
    MAX_SAT_DEV_CNT
}sat_hw_ch_s;

#else

typedef enum hw_ch
{
    HW_PL_TRANSCELESTIAL = 0,
    HW_S_BAND,
    HW_X_BAND,
    HW_PL_STS300,
    HW_ADCS,
    HW_PROP_UNIT_THRUSTER,
    HW_UHF,
    HW_PL_SCANWAY,
    HW_PL_NETRA,
    HW_EDGE_BRD,
    HW_OBC_PS_GPS_STD_PL_BRD,
    HW_HRM,
    HW_PL_SERVER,
    HW_GPS,
	HW_EDGE1,
	HW_EDGE2,
	HW_PS_GEN2,
	HW_NIC1,
	HW_SSD1,
	HW_SSD2,
	HW_SSD3,
	HW_SSD4,
    MAX_SAT_DEV_CNT
}sat_hw_ch_s;

#endif

/**
 * @brief  Radio Module ID type enumeration
 */
typedef enum
{
    COMMS_S_BAND = 1,     ///< S Band Id
    COMMS_UHF           = 2,  ///< UHF Id
    COMMS_SBAND_IQS     = 3,  ///< IQS S-Band Id
    GS2_BACK_DOOR_SOC   = 4,  ///< GS2 back door Id
    COMMS_X_BAND        = 5,  ///< X Band Id
    MAX_RADIO_MOD         ///< Max Radio Id
}e_radio_id;

typedef struct
{
    uint8_t hw_sts;
    uint8_t sw_sts;
}sat_dev_sts_s;

//extern volatile uint8_t EPS_PS_ON_DEFLT_DISABLE ;
extern volatile uint8_t EPS_HRM_ON_DEFLT ;

extern sat_btry_info_s sat_btry_info;
extern sat_dev_sts_s sat_dev_sts[MAX_SAT_DEV_CNT];
extern uint8_t kernel_init_done;

extern s_tc_dbg_info tc_dbg_info[MAX_TCTM_DBG_INFO];
extern s_tm_dbg_info tm_dbg_info[MAX_TCTM_DBG_INFO];

#endif /* _EXO_COMMON_H_ */
