#ifndef CAN_STACK_H_
#define CAN_STACK_H_
#include "cantp_types.h"

typedef buf_indication_res_type (*cantp_rx_indication_callback_func_type)(cantp_u8*, cantp_u16);

/**
 * @brief This function is used by cantp_core layer to copy received data to cantp_fifo layer.
 *
 * @param[in] id The identifier for the received service data unit (SDU).
 * @param[in] pduInfoPtr Pointer point to the data struct.
 * @param[out] bufferSizePtr Buffer size after this copy.
 * @return buf_req_return_type The result of the buffer request operation.
 */
buf_req_return_type CanTp_CopyRxData (
    pdu_id_type id,
    const pdu_info_type_t* pduInfoPtr,
    pdu_length_type* bufferSizePtr
);

/**
 * @brief This function is utilized by the cantp_core layer to copy data intended for transmission.
 *
 * @param[in] id The identifier for the transmit service data unit (SDU).
 * @param[in] pduInfoPtr A pointer to the data structure.
 * @param[in] retryInfoPtr A pointer to a structure indicating the types of this call.
 * @param[out] availableDataPtr A pointer to the buffer size available after this copy operation.
 * @return buf_req_return_type The result of the buffer request operation.
 */
buf_req_return_type CanTp_CopyTxData (
    pdu_id_type id,
    const pdu_info_type_t * pduInfoPtr,
    const retry_info_type_t * retryInfoPtr,
    pdu_length_type * availableDataPtr
);
/**
 * @brief This function will called to get pending data length in fifo.
 * 
 * @param sduId sdu id.
 * @return cantp_u32 pending length
 * 
 * //TODO remove this function after update fifo. use CanTp_CopyTxData to get pending length instead.
 */
cantp_u32 CanTp_GetPendingLength(sdu_id_type sduId);
/**
 * @brief This function is employed by the cantp_core layer to notify the cantp layer of the
 *        reception of a message.
 *
 * @param[in] id The identifier for the received service data unit (SDU).
 * @param[in] pduInfoPtr A pointer to the data structure containing the received message information.
 * @param[in] tpSduLength The required length for this service data unit.
 * @param[out] bufferSizePtr A pointer to the buffer size that cantp can offer for this reception.
 * @return buf_req_return_type The result of the buffer request operation for the received message.
 */
buf_req_return_type CanTp_StartOfReception (
    pdu_id_type id,
    const pdu_info_type_t * pduInfoPtr,
    pdu_length_type tpSduLength,
    pdu_length_type * bufferSizePtr
);

/**
 * @brief This function is used by cantp_core layer to indicate cantp layer the reception of one msg.
 *
 * @param[in] sduId SduId
 * @param[in] result Reception result
 */
void CanTp_RxIndication (pdu_id_type sduId, cantp_return_type result);

/**
 * @brief This function is used by cantp_core layer to confirm cantp layer the transmit of one msg.
 *
 * @param[in] sduId SduId
 * @param[in] res Transmit result
 */
void CanTp_TxConfirmation (pdu_id_type sduId, cantp_core_res_type res);

/**
 * @brief This function initializes the cantp module.
 *
 * @note This function calls the FLEX_CAN's API to initialize the FLEX_CAN module. Prior to calling
 *       this function, ensure that the peripheral clock for FLEX_CAN is enabled.
 * @param[in] configPtr A pointer to the configuration structure for cantp.
 * @return cantp_return_type The result of the initialization operation.
 */
cantp_return_type CanTp_Init(const cantp_config_t* configPtr);

/**
 * @brief Main function of cantp.
 * @note This function needs to be called as frequently as possible.
 *
 */
void CanTp_MainFunction(void);

/**
 * @brief This function copies received data to a specified location.
 *
 * @note If the message buffer for the given sduId is not empty, this function will copy the received
 *       SDU to the specified location and return true; otherwise, it will return false directly.
 * @param[in] sduId The SDU identifier.
 * @param[in] pduInfoPtr Pointer to the location where the received data should be stored.
 * @return cantp_copy_res_type The result of the copy operation.
 */
cantp_copy_res_type CanTp_CopyRxSdu(pdu_id_type pduId, pdu_info_type_t* pduInfoPtr);

/**
 * @brief Call this function 1ms period to update the cantp timer.
 */
void CanTp_TimeService();

/**
 * @brief This function is used to transmit an msg to bus.
 *
 * @param[in] sduId The SDU identifier
 * @param[in] sduInfoPtr Pointer to the location where the transmit data location.
 * @return cantp_return_type
 */
cantp_return_type CanTp_Transmit(sdu_id_type sduId, pdu_info_type_t* sduInfoPtr);
#endif