#ifndef VMF_NNM_FIFOQ_MANAGER_H
#define VMF_NNM_FIFOQ_MANAGER_H

#include <stdint.h>
#include <stdbool.h>

/* Basic FIFO queue management */
void VMF_NNM_Fifoq_Manager_Init(void);
void VMF_NNM_Fifoq_Manager_Destroy(void);
void VMF_NNM_Fifoq_Manager_Wakeup(void);
void VMF_NNM_Fifoq_Manager_Suspend(void);
void VMF_NNM_Fifoq_Manager_Resume(void);
void VMF_NNM_Fifoq_Manager_Status_Code_Enqueue(unsigned int job_id, int status_code);
bool VMF_NNM_Fifoq_Manager_Get_Fifoq_Allocated(void);

/* Image queue */
int  VMF_NNM_Fifoq_Manager_Image_Get_Free_Buffer(uint32_t *buf_addr, uint32_t *phy_addr, int *buf_size, int timeout_ms, bool droppable);
int  VMF_NNM_Fifoq_Manager_Image_Enqueue(uint32_t total, uint32_t index, uint32_t buf_addr, uint32_t phy_addr, int buf_size, int flags, bool is_last);
int  VMF_NNM_Fifoq_Manager_Image_Put_Free_Buffer(uint32_t buf_addr, uint32_t phy_addr, int buf_size, int flags);

/* Result queue */
int  VMF_NNM_Fifoq_Manager_Result_Get_Free_Buffer(uint32_t *buf_addr, uint32_t *phy_addr, int *buf_size, int timeout_ms);
int  VMF_NNM_Fifoq_Manager_Result_Enqueue(uint32_t buf_addr, uint32_t phy_addr, int buf_size, int timeout_ms, bool is_last);
int  VMF_NNM_Fifoq_Manager_Result_Dequeue(uint32_t *buf_addr, uint32_t *phy_addr, int *buf_size, int timeout_ms);
int  VMF_NNM_Fifoq_Manager_Result_Put_Free_Buffer(uint32_t buf_addr, uint32_t phy_addr, int buf_size, int flags);

/* Buffer allocation / release */
int  VMF_NNM_Fifoq_Manager_Allocate_Buffer(int img_buf_count, int img_buf_size, int res_buf_count, int res_buf_size);
void VMF_NNM_Fifoq_Manager_Release_All_Buffer(void);

/* Thread entry points (used with pthread_create) */
void *VMF_NNM_Fifoq_Manager_Enqueue_Image_Thread(void *arg);
void *VMF_NNM_Inference_Image_Dispatcher_Thread(void *arg);

/* NNM version / model loading */
void VMF_NNM_Get_Version(uint32_t *major, uint32_t *minor, uint32_t *patch, uint32_t *build);
int  VMF_NNM_Load_Model_From_File(const char *model_path);

#endif /* VMF_NNM_FIFOQ_MANAGER_H */
