#pragma once

#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "queue.h"

#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/irq.h"

struct GobotRPC_NI_Package_Transport {
    char data[32];
    uint length;
    uint index;
};

enum I2C_WRITE_STATE {
    I2C_WRITE_STATE_FIRST,
    I2C_WRITE_STATE_LENGTH,
    I2C_WRITE_STATE_DATA,
};

enum I2C_READ_STATE {
    I2C_READ_STAGE_FIRST,
    I2C_READ_STAGE_DONE,
    I2C_READ_STAGE_WIP,
    I2C_READ_STAGE_INVALID
};

enum I2C_SLAVE_EVENT {
    I2C_SLAVE_RECEIVE,
    I2C_SLAVE_REQUEST,
    I2C_SLAVE_FINISH
};

class GobotRPC_NI_Hardware {

};

struct GobotRPC_NI_Hardware_RP2040_I2C_PreTxQueues {
    QueueHandle_t isrPreTxQueue;
    QueueHandle_t isrTXQueue;
};

class GobotRPC_NI_Hardware_RP2040_I2C : public GobotRPC_NI_Hardware {
    uint core;

    QueueHandle_t isrPreTxQueue;
    QueueHandle_t isrTXQueue;
    QueueHandle_t isrRXQueue;
    TaskHandle_t preTxTaskHandle;

    uint i2cSDA_PIN;
    uint i2cSCL_PIN;
    uint int_PIN;
    uint8_t i2cAddress;

    I2C_WRITE_STATE writeState = I2C_WRITE_STATE_FIRST;
    I2C_READ_STATE readState = I2C_READ_STAGE_INVALID;

    GobotRPC_NI_Package_Transport rxPackage;
    GobotRPC_NI_Package_Transport txPackage;
    
public:
    i2c_inst_t * i2c_inst;

    GobotRPC_NI_Hardware_RP2040_I2C(
        xQueueHandle TXQueue, xQueueHandle RXQueue, uint core,
        i2c_inst_t * i2c_inst,
        uint8_t i2cAddress,
        uint i2cSDA_PIN, uint i2cSCL_PIN, uint int_PIN
    );

    void onI2CIRQ(I2C_SLAVE_EVENT event, BaseType_t * xHigherPriorityTaskWoken);
    void preTxTask();
};

extern GobotRPC_NI_Hardware_RP2040_I2C * g_gobotrpc_ni_hardware_rp2040_i2c;
