#pragma once

#include "mcp2521_hardware_esp.hpp"

#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

struct spi_message_t {
    spi_transaction_t *transaction;
    QueueHandle_t queue;
    spi_device_handle_t spi_device_handle;
};

/**
 * @brief Hardware handle for MCP2521 over SPI in a multi-Bus-Setup on ESP32 
 * This should not be created directly, use the MCP2521_HardwareHandleFactory_ESPBus instead
 */
class MCP2521_HardwareHandle_ESPBus : public MCP2521_HardwareHandle_ESP {
    using MCP2521_HardwareHandle_ESP::MCP2521_HardwareHandle_ESP;
private:
    QueueHandle_t send_queue;
    QueueHandle_t receive_queue;

    /**
     * @brief Wrapper around the spi_transmit function, that locks the spiMutex before calling spi_transmit.
     * The muxtex is shared with all other MCP2521_HardwareHandle_ESPBus instances created by the same MCP2521_HardwareHandleFactory_ESPBus
     * @overload
     * 
     * @param t ESP32 SPI Transaction struct
     */
    void spi_transmit(spi_transaction_t *t);
public:
    MCP2521_HardwareHandle_ESPBus(
        QueueHandle_t send_queue,
        spi_host_device_t spi_host,
        spi_bus_config_t * bus_config,
        gpio_num_t cs, 
        gpio_num_t int_pin
    );

    void initPins(
        gpio_num_t int_pin
    );
};
