#ifndef __MOZEN_PROTOCOL_H
#define __MOZEN_PROTOCOL_H

#include <stdint.h>
#include <stdbool.h>

#define MOZEN_PROTOCOL_SOF 0x5AA5 // ֡ͷ

// --- Core Protocol Data Structures ---

#pragma pack(1)
/**
 * @brief Represents the header of a Mozen protocol frame.
 *        The payload data follows this header directly in the buffer.
 */
typedef struct 
{
    uint16_t sof;
    uint8_t  command_id;
    uint16_t frame_length;
} mozen_frame_header_t;
#pragma pack()

/**
 * @brief Command handler callback type.
 * @param context User context provided during registration.
 * @param cmd_id The command ID of the received frame.
 * @param data Pointer to the 'Data' field of the received frame.
 * @param length The length of the 'Data' field.
 */
typedef void (*mozen_cmd_handler_t)(void *context, uint8_t cmd_id, const uint8_t *data, uint16_t length);

/**
 * @brief Custom raw frame handler, used for legacy protocol compatibility or custom validation.
 * @param context User context.
 * @param raw_frame The complete raw frame data.
 * @param length The length of the complete raw frame.
 * @return true if the frame is handled and should not be processed further, false otherwise.
 */
typedef bool (*mozen_raw_frame_handler_t)(void *context, const uint8_t *raw_frame, uint16_t length);

/**
 * @brief Transport TX callback type.
 * @param frame Complete protocol frame buffer (header + payload + crc).
 * @param len Frame length in bytes.
 * @return 0 on success, negative value on failure.
 */
typedef int (*mozen_tx_fn_t)(const uint8_t *frame, uint16_t len);

// Max number of registered command handlers
#define MOZEN_MAX_HANDLERS      10 

// RX State Machine States
typedef enum 
{
    MOZEN_RX_STATE_WAIT_SOF1,
    MOZEN_RX_STATE_WAIT_SOF2,
    MOZEN_RX_STATE_WAIT_HEADER,
    MOZEN_RX_STATE_WAIT_DATA,
} mozen_rx_state_t;

/**
 * @brief Mozen Protocol Instance Context
 *        Contains state and configurations for a single protocol instance.
 */
typedef struct 
{
    // Buffers and configuration
    uint8_t *rx_buffer; 
    uint16_t rx_buffer_size;
    uint8_t *tx_buffer_main; // Main TX buffer
    uint8_t *tx_buffer_irq; // IRQ TX buffer
    uint16_t tx_buffer_size;
    
    // Callbacks
    mozen_tx_fn_t tx_fn;
    void *user_context;
    
    // Command Handlers
    struct 
    {
        uint8_t cmd_id;
        mozen_cmd_handler_t handler;
    } handlers[MOZEN_MAX_HANDLERS];
    uint8_t handler_count;

    mozen_cmd_handler_t default_handler;
    mozen_raw_frame_handler_t raw_frame_handler;

    // RX State Machine
    mozen_rx_state_t rx_state;
    uint16_t rx_index;
    uint16_t expected_data_len;
    uint32_t last_rx_time_ms; // For timeout handling
} mozen_protocol_t;

// --- API Functions ---

void mozen_protocol_init(mozen_protocol_t *prot, 
                         uint8_t *rx_buf, uint16_t rx_buf_size, 
                         uint8_t *tx_buf_main, uint8_t *tx_buf_irq, uint16_t tx_buf_size,
                         mozen_tx_fn_t tx_fn, void *user_context);

int mozen_protocol_register_handler(mozen_protocol_t *prot, uint8_t cmd_id, mozen_cmd_handler_t handler);

void mozen_protocol_set_default_handler(mozen_protocol_t *prot, mozen_cmd_handler_t handler);

void mozen_protocol_set_raw_handler(mozen_protocol_t *prot, mozen_raw_frame_handler_t handler);

void mozen_protocol_feed_byte(mozen_protocol_t *prot, uint8_t byte, uint32_t current_time_ms);

void mozen_protocol_tick(mozen_protocol_t *prot, uint32_t current_time_ms, uint32_t timeout_ms);

int mozen_protocol_send_frame(mozen_protocol_t *prot, uint8_t command_id, const uint8_t* data, uint16_t length, bool use_irq_buffer);

uint16_t mozen_protocol_crc16_modbus(const uint8_t *data, uint16_t length);

uint16_t mozen_protocol_checksum(const uint8_t *data, uint32_t len);

#endif // __MOZEN_PROTOCOL_H
