#ifndef AIW_SOC_PEER_H
#define AIW_SOC_PEER_H

#include "ai_wire.h"

typedef struct {
    const void *frame_handle;
    uint64_t capture_baseline_seq;
    uint64_t source_frame_seq;
    /* Set only by a camera adapter that requests a new exposure after the
       AI_REQUEST is received; a cached buffer must leave this false. */
    bool exposure_started_after_request;
} aiw_soc_capture;

typedef struct {
    bool hand_present;
    /* Per-output nail-region allow mask. PWM outside this mask is forced to 0. */
    uint8_t nail_channel_mask[AIW_MAX_CHANNELS];
    uint8_t pwm[AIW_MAX_CHANNELS];
} aiw_soc_inference;

typedef bool (*aiw_soc_capture_fn)(void *context, const aiw_ticket *request,
                                   aiw_soc_capture *capture);
typedef bool (*aiw_soc_infer_fn)(void *context, const aiw_soc_capture *capture,
                                 uint16_t channels,
                                 aiw_soc_inference *inference);

typedef struct {
    uint64_t session_id;
    uint64_t last_source_frame_seq;
    uint32_t calibration_id;
    uint32_t last_ticket_id;
    uint32_t capture_failures;
    uint32_t rejected_requests;
    uint32_t inference_failures;
    uint16_t channels;
    bool active;
    aiw_soc_capture_fn capture_fresh_frame;
    aiw_soc_infer_fn infer_nail_pwm;
    void *context;
} aiw_soc_peer;

typedef enum {
    AIW_SOC_PEER_RESPONSE_ENCODED = 0,
    AIW_SOC_PEER_INVALID_ARGUMENT,
    AIW_SOC_PEER_INVALID_REQUEST,
    AIW_SOC_PEER_SESSION_MISMATCH,
    AIW_SOC_PEER_REPLAYED_TICKET,
    AIW_SOC_PEER_CAPTURE_FAILED,
    AIW_SOC_PEER_STALE_FRAME,
    AIW_SOC_PEER_RESPONSE_TOO_LARGE
} aiw_soc_peer_status;

/* The peer object must be zero-initialized. session_id must come from a
   non-repeating session source, and the camera adapter must flush cached frames
   when a new session starts. Neither property is provided by this module. */
bool aiw_soc_peer_init(aiw_soc_peer *peer, uint64_t session_id,
                       uint32_t calibration_id, uint16_t channels,
                       aiw_soc_capture_fn capture_fresh_frame,
                       aiw_soc_infer_fn infer_nail_pwm, void *context);

/* Process one complete AI_REQUEST. No response is produced for malformed,
   mismatched, duplicate, or stale requests. A model failure produces a valid
   hand-absent / zero-PWM result for the fresh frame. */
aiw_soc_peer_status aiw_soc_peer_process(
    aiw_soc_peer *peer, const uint8_t *request_packet, size_t request_length,
    uint8_t *response_packet, size_t response_capacity,
    size_t *response_length);

#endif
