#ifndef K230_VDEC_H
#define K230_VDEC_H

#include <cstdint>
#include <vector>
#include <stdexcept>
#include <cstring>
#include "k_vdec_comm.h"

/**
 * @brief Enumeration of supported video decoder types
 * Defines the different video compression standards that can be used
 */
enum DecoderType {
    VDEC_UNKNOWN, ///< Unknown/unsupported codec type
    VDEC_H264,   ///< H.264 / AVC (Advanced Video Coding) standard
    VDEC_H265,   ///< H.265 / HEVC (High Efficiency Video Coding) standard
    VDEC_JPEG    ///< JPEG (Joint Photographic Experts Group) image compression standard
};

struct DecoderConfig {
    DecoderType type;       ///< Video codec type (H264/H265/JPEG)
    uint32_t max_width;     ///< Max width of the input video frame in pixels
    uint32_t max_height;    ///< Max height of the input video frame in pixels
    uint32_t input_buf_num; ///< Number of input buffers for encoded streams
    uint32_t output_buf_num;///< Number of output buffers for decoded frames

    /**
     * @brief Constructor for DecoderConfig with default values
     * @param dec_type Video codec type
     * @param buf_num Number of output buffers (default: 6)
     * @param w Max input frame width in pixels
     * @param h Max input frame height in pixels
     */
    DecoderConfig(DecoderType dec_type, uint32_t in_buf_num = 4, uint32_t out_buf_num = 6,uint32_t w = 1920, uint32_t h=1088);

};

/**
 * @brief Video decoder class managing a single decoding channel
 * Provides complete lifecycle management and operation of a video decoding instance,
 * handling stream input, decoding processing, and decoded frame output
 */
class VideoDecoder {
public:
    /**
     * @brief Constructor initializing with decoder configuration
     * @param config Decoder configuration parameters
     */
    VideoDecoder(const DecoderConfig& config);

    /**
     * @brief Destructor cleaning up decoder resources
     */
    ~VideoDecoder();

    /**
     * @brief Creates and initializes the decoder instance
     * Allocates necessary resources and sets up decoding parameters
     * @return 0 on success, non-zero error code on failure
     */
    int create();

    /**
     * @brief Starts the decoder operation
     * Puts the decoder into active state ready to process input streams
     * @return 0 on success, non-zero error code on failure
     */
    int start();

    /**
     * @brief Sends encoded stream data to the decoder for processing
     * @param data Pointer to the encoded stream data
     * @param size Size of the encoded stream data in bytes
     * @param timestamp Presentation timestamp for the stream data
     * @param timeout Maximum time to wait for stream submission in milliseconds (default: -1)
     * @return 0 on success, non-zero error code on failure
     */
    int send_stream(const uint8_t* data, uint32_t size,uint64_t timestamp = 0, int timeout = -1);

    /**
     * @brief Retrieves decoded frame data from the decoder
     * @param frame Output parameter to store the decoded frame data
     * @param timeout Maximum time to wait for available frame data in milliseconds (default: -1)
     * @return 0 on success, non-zero error code on failure
     */
    int get_frame(k_video_frame_info& frame, int timeout = -1);

    /**
     * @brief Releases the decoded frame buffer back to the decoder
     * Must be called after processing the frame data to avoid memory leaks
     * @param frame The decoded frame to release
     * @return 0 on success, non-zero error code on failure
     */
    int release_frame(k_video_frame_info& frame);

    /**
     * @brief Stops the decoder operation
     * Pauses decoding processing while preserving allocated resources
     * @return 0 on success, non-zero error code on failure
     */
    int stop();

    /**
     * @brief Destroys the decoder instance
     * Releases all allocated resources and cleans up the decoder
     * @return 0 on success, non-zero error code on failure
     */
    int destroy();

    /**
     * @brief Gets the hardware channel ID of the decoder
     * @return Channel ID as an integer
     */
    int get_channel_id() const { return channel_id_; }

private:
    /**
     * @brief Enumeration of possible decoder states
     * Represents the lifecycle stages of the decoder instance
     */
    enum DecoderState {
        CREATED,    ///< Decoder created but not started
        STARTED,    ///< Decoder actively processing streams
        STOPPED,    ///< Decoder stopped but not destroyed
        DESTROYED   ///< Decoder destroyed and resources released
    };

    k_u32 channel_id_;             ///< Hardware channel identifier for the decoder
    DecoderState state_;           ///< Current operational state of the decoder
    DecoderConfig config_;         ///< Stored decoder configuration parameters
    k_vdec_stream input_stream_;   ///< Internal structure for input stream data
    k_u32 private_output_pool_id_; ///< Identifier for internal buffer pool
    k_u32 private_input_pool_id_;  ///< Identifier for internal input buffer pool


    /**
     * @brief Sets up input and output buffers for the decoder
     * Allocates and initializes buffer pools for stream and frame data
     * @return 0 on success, non-zero error code on failure
     */
    int _setup_buffers();

    /**
     * @brief Releases the buffer pools used by the decoder
     */
    void _release_buffers();

};

#endif // K230_VDEC_H