#pragma once

#include "ggml.h"
#include "ggml-backend.h"

#ifdef  __cplusplus
extern "C" {
#endif

// backend API
GGML_BACKEND_API ggml_backend_t ggml_backend_hexagon_init(void);

GGML_BACKEND_API bool ggml_backend_is_hexagon(ggml_backend_t backend);

GGML_BACKEND_API ggml_backend_reg_t ggml_backend_hexagon_reg(void);

// Mega-kernel transport self-test. Allocates 3 small FastRPC buffers
// (descriptor, ack, logits), ships a minimal-but-valid htp_mega_descriptor
// to the DSP via HTP_OP_QWEN35_COMPILE, invokes HTP_OP_QWEN35_STEP, reads
// back the stub-produced logits (should be all zeros), and verifies.
//
// Returns 0 on success, negative on failure. Logs diagnostic to stderr.
// Scope: proves the host↔DSP transport for the mega-kernel entry points
// with the skeleton stubs from qwen35-forward-ops.c. No real inference.
GGML_BACKEND_API int ggml_backend_hexagon_qwen35_selftest(ggml_backend_t backend);

// Mega-kernel graph compiler. Walks the given ggml_cgraph, emits an
// htp_mega_descriptor (ops + tensor table + buffer table), registers every
// distinct ggml_backend_buffer_t the graph touches as a persistent FastRPC
// buffer, ships everything to the DSP in a single HTP_OP_QWEN35_COMPILE
// message, and stores the descriptor in the DSP's static slot.
//
// Tensor table entries carry (buffer_id, offset_in_bytes) so the DSP
// interpreter can resolve any tensor id to a pointer in O(1). Op entries
// reference src/dst tensor ids; unsupported GGML ops are emitted as
// HTP_MEGA_NOP (the interpreter will skip them).
//
// logits_tensor identifies which tensor's data should be copied back to the
// host when a subsequent step call completes. For a real Qwen3.5 model this
// is the lm_head output tensor; for a test graph it can be any intermediate
// node. Pass NULL to default to the last cgraph node.
//
// Returns 0 on success, negative on failure.
GGML_BACKEND_API int ggml_backend_hexagon_qwen35_compile(
        ggml_backend_t backend,
        struct ggml_cgraph * cgraph,
        struct ggml_tensor * logits_tensor);

// Invokes one forward-pass step of the compiled mega-kernel on the DSP.
// The descriptor must have been shipped via ggml_backend_hexagon_qwen35_compile.
// input_token_id + position identify the current decode input; logits_out
// receives n_logits floats (must be ≥ descriptor vocab_size).
GGML_BACKEND_API int ggml_backend_hexagon_qwen35_step(
        ggml_backend_t backend,
        uint32_t       input_token_id,
        int32_t        position,
        float *        logits_out,
        size_t         n_logits);

#ifdef  __cplusplus
}
#endif
