/**
 * @file pipeline.h
 * @brief Definition of the PipeLine class for handling sensor input, display output, and AI frame processing.
 * 
 * This class provides an integrated data pipeline for:
 * - Capturing frames from the camera sensor.
 * - Converting frames to AI tensors.
 * - Displaying images using the K230 display system.
 * - Managing buffer allocation and resource cleanup.
 * 
 * Dependencies:
 * - OpenCV (for cv::Mat operations)
 * - K230 SDK components (sensor, display, MPI, KPU)
 */

#ifndef PIPELINE_H_
#define PIPELINE_H_

#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/opencv.hpp>
#include <Arduino.h>

#include "k230_display.h"
#include "k230_sensor.h"
#include "mpi_sys_api.h"
#include "kpu.h"

/**
 * @class PipeLine
 * @brief A unified interface for video capture, AI tensor generation, and display rendering.
 */
class PipeLine
{
public:
    /**
     * @brief Construct a new PipeLine object.
     * 
     * @param sensor_id          Sensor device ID.
     * @param display_type       Display type (e.g., "ST7701").
     * @param ai_frame_width     Width of the frame used for AI processing.
     * @param ai_frame_height    Height of the frame used for AI processing.
     * @param display_width      Display output width.
     * @param display_height     Display output height.
     */
    PipeLine(int sensor_id,
             std::string &display_type,
             size_t ai_frame_width,
             size_t ai_frame_height,
             size_t display_width,
             size_t display_height);

    /**
     * @brief Destroy the PipeLine object and release all allocated resources.
     */
    ~PipeLine();

    /**
     * @brief Retrieve a video frame from the sensor.
     * 
     * @return k_video_frame_info Structure containing frame metadata and buffer information.
     */
    k_video_frame_info get_frame();

    /**
     * @brief Convert the current frame to a runtime tensor for AI inference.
     * 
     * @return runtime_tensor The generated tensor.
     */
    runtime_tensor get_tensor();

    /**
     * @brief Release the currently held AI tensor resources.
     */
    void release_tensor();

    /**
     * @brief Release the current video frame back to the buffer pool.
     */
    void release_frame();

    /**
     * @brief Display the current frame on the connected display.
     */
    void show_image();

public:
    cv::Mat osd_frame;  ///< Frame buffer for on-screen display (OpenCV format).

private:
    // Frame dimensions
    size_t ai_frame_width_;
    size_t ai_frame_height_;
    size_t display_width_;
    size_t display_height_;

    // Sensor and display handlers
    Sensor *sensor = nullptr;
    Display *display = nullptr;

    // Configuration parameters
    int sensor_id_;
    std::string display_type_;

    // Frame and tensor buffers
    k_video_frame_info frame_info;
    dims_t tensor_shape;
    uintptr_t frame_virt_addr = 0;
    uintptr_t frame_phy_addr  = 0;
    runtime_tensor frame_tensor;

    // OSD (On-Screen Display) buffer info
    VbBuffer osd_frame_buffer;
    k_video_frame_info osd_frame_info;
    k_s32 osd_frame_pool_id = VB_INVALID_POOLID;
};

#endif  // PIPELINE_H_
