#pragma once

#include <why-error.h>
#include <why-fd.h>
#include <jqueue.h>

#include <cstdint>
#include <atomic>


struct CANFrame
{
    uint32_t id;
    uint8_t dlc;
    uint8_t data[8];
};

class CAN_JF0815_HW
{
public:
    static const int IRQ_XMIT_DONE = 1001;
    static const int IRQ_RECV_READY = 1002;

public:
    CAN_JF0815_HW(const std::string& can_iface);
    ~CAN_JF0815_HW();

    void begin_xmit(const CANFrame&);
    CANFrame commit_recv();

    bool xmit_busy() { return _frame_to_send_valid.load(); }

private:
    void _hw_loop();
    void _hw_send_requested_func();
    void _hw_recv_ready_func();

private:
    CANFrame _frame_to_send;
    std::atomic<bool> _frame_to_send_valid = false;

    CANFrame _frame_received;
    std::atomic<bool> _frame_received_valid = false;

    Why::FD _can_socket;
    Why::FD _send_requested_event;
    Why::FD _quit_requested_event;

    std::thread _hw_thread;
};
