#include "hal_data.h"
#include "dcds.h"
#include <realityai/baby_cry_10_sm_model.h>

static rai_data_collector_frame_buffer_t g_frame_buf[8];
static rai_data_collector_callback_args_t g_callback_args;

// PMOD1-7
void dcds_debug_gpio(int en){
    R_BSP_PinWrite(BSP_IO_PORT_04_PIN_12, (en != 0) ? BSP_IO_LEVEL_HIGH : BSP_IO_LEVEL_LOW);
}

fsp_err_t dcds_init(void)
{
    fsp_err_t err = FSP_SUCCESS;

    /* Open Data Collector */
    err = RM_RAI_DATA_COLLECTOR_Open(&g_rai_data_collector0_ctrl, &g_rai_data_collector0_cfg);
    assert(err == FSP_SUCCESS);

    /* Open Data Shipper */
    err = RM_RAI_DATA_SHIPPER_Open(&g_rai_data_shipper0_ctrl, &g_rai_data_shipper0_cfg);
    assert(err == FSP_SUCCESS);

    return err;
}

fsp_err_t dcds_write(int16_t* buf, uint32_t size)
{
    // p_model for AI Live Monitor
    struct rai_model_struct* p_model = get_baby_cry_10_sm_model();
    fsp_err_t err = FSP_SUCCESS;
    DCDS_DTYPE* p_fb = NULL;
    assert( size == DCDS_FRAME_SIZE );

    /* Get DC frame buffers */
    err = RM_RAI_DATA_COLLECTOR_ChannelBufferGet(&g_rai_data_collector0_ctrl, 0, (void*)&p_fb);
    assert(err == FSP_SUCCESS);

    /* Copy to Frame Buffer */
    memcpy(p_fb, buf, size);

    /* Ship Buffer */
    rai_data_shipper_write_params_t arg;

    // enabling AI live monitor
    arg.diagnostic_data_len = (uint8_t)RealityAI_get_monitor_data_size(p_model);;
    arg.p_diagnostic_data = (uint8_t*)RealityAI_get_monitor_data(p_model);
    arg.events = 0;
    arg.p_sensor_data = &g_callback_args;

    err = g_rai_data_shipper0.p_api->write(&g_rai_data_shipper0_ctrl, &arg);
    assert(err == FSP_SUCCESS);

    return err;
}

void rai_data_collector0_callback(const rai_data_collector_callback_args_t *p_args)
{
    g_callback_args.frame_buf_len = p_args->frame_buf_len;
    g_callback_args.frames = p_args->frames;
    g_callback_args.instance_id = p_args->instance_id;
    for(uint8_t i = 0; i < p_args->frames; i++){
        g_frame_buf[i] = p_args->p_frame_buf[i];
    }
    g_callback_args.p_frame_buf = g_frame_buf;
#if !DCDS_ENABLE_SHIPPER
    fsp_err_t err = RM_RAI_DATA_COLLECTOR_BufferRelease(&g_rai_data_collector0_ctrl);
    assert(err == FSP_SUCCESS);
#endif
}

void rai_data_collector0_error_callback(const rai_data_collector_error_callback_args_t *p_args)
{
    (void)p_args;
    assert(0); // trap
}

void rai_data_shipper0_callback(rai_data_shipper_callback_args_t *p_args)
{
    assert(p_args->result != RM_COMMS_EVENT_ERROR);
#if DCDS_ENABLE_SHIPPER
    g_rai_data_collector0.p_api->bufferRelease(&g_rai_data_collector0_ctrl);
#endif
}

