#ifndef GIGASTT_H
#define GIGASTT_H

/* Auto-generated by cbindgen. Do not edit. */

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

/**
 * Opaque handle to the inference engine.
 *
 * The Kotlin side sees this as a `Long` (pointer-sized integer).
 */
typedef struct GigasttGigasttEngine GigasttGigasttEngine;

/**
 * Opaque handle to a streaming transcription session.
 *
 * Holds a checked-out `SessionTriplet` and a `StreamingState`. The triplet is
 * returned to the pool when `gigastt_stream_free` is called.
 */
typedef struct GigasttGigasttStream GigasttGigasttStream;

/**
 * Load the ONNX models from `model_dir` and create an inference engine.
 *
 * Uses the default pool size (4). For mobile devices, prefer
 * `gigastt_engine_new_with_pool_size` with `pool_size = 1` to reduce RAM.
 *
 * # Safety
 * `model_dir` must be a valid, null-terminated UTF-8 string.
 * Returns a pointer to a `GigasttEngine` on success, or `NULL` on failure.
 */
gigastt_ struct GigasttGigasttEngine *gigastt_engine_new(const char *model_dir);

/**
 * Load the ONNX models with a custom session pool size.
 *
 * `pool_size` controls how many concurrent inference sessions are kept in
 * memory. Each session loads the full encoder, so RAM scales linearly:
 * - pool_size = 1: ~350 MB (recommended for mobile)
 * - pool_size = 4: ~560 MB (default desktop/server)
 *
 * # Safety
 * `model_dir` must be a valid, null-terminated UTF-8 string.
 * Returns a pointer to a `GigasttEngine` on success, or `NULL` on failure.
 */
gigastt_
struct GigasttGigasttEngine *gigastt_engine_new_with_pool_size(const char *model_dir,
                                                               uintptr_t pool_size);

/**
 * Transcribe an audio file and return the recognized text as a newly allocated C string.
 *
 * # Safety
 * - `engine` must be a non-null pointer returned by `gigastt_engine_new` and not yet freed.
 * - `wav_path` must be a valid, null-terminated UTF-8 string.
 * - NOT thread-safe (single-threaded-per-handle): no thread may call
 *   `gigastt_engine_free` on `engine` concurrently with this call. The early
 *   `disposed` check rejects an already-freed handle but does not close the
 *   in-call race.
 *
 * Returns a pointer to a NUL-terminated UTF-8 string on success, or `NULL` on failure.
 * The caller **must** free the returned string with `gigastt_string_free`.
 */
gigastt_ char *gigastt_transcribe_file(struct GigasttGigasttEngine *engine, const char *wav_path);

/**
 * Free a C string previously returned by `gigastt_transcribe_file` or the
 * streaming functions.
 *
 * # Safety
 * `s` must be a pointer returned by one of the transcription functions and not
 * yet freed, or `NULL` (in which case this is a no-op).
 */
gigastt_ void gigastt_string_free(char *s);

/**
 * Free an inference engine previously created by `gigastt_engine_new`.
 *
 * # Safety
 * `engine` must be a pointer returned by `gigastt_engine_new` and not yet freed,
 * or `NULL` (in which case this is a no-op). NOT thread-safe
 * (single-threaded-per-handle): the caller must ensure no other call using this
 * pointer runs concurrently with this free.
 */
gigastt_ void gigastt_engine_free(struct GigasttGigasttEngine *engine);

/**
 * Quantize the FP32 encoder model to INT8 in-place.
 *
 * Looks for `v3_e2e_rnnt_encoder.onnx` inside `model_dir` and produces
 * `v3_e2e_rnnt_encoder_int8.onnx` in the same directory.
 * If the INT8 file already exists and `force` is `false`, returns immediately.
 *
 * # Safety
 * `model_dir` must be a valid, null-terminated UTF-8 string.
 *
 * Returns a newly allocated C string on both success and error.
 * The caller **must** free the returned string with `gigastt_string_free`.
 */
gigastt_ char *gigastt_quantize_model(const char *model_dir, bool force);

/**
 * Create a new streaming session.
 *
 * Checks out a `SessionTriplet` from the engine pool and creates a fresh
 * `StreamingState`. The triplet is held for the lifetime of the stream and
 * returned to the pool by `gigastt_stream_free`.
 *
 * # Safety
 * `engine` must be a valid pointer returned by `gigastt_engine_new`.
 * Returns a pointer to a `GigasttStream` on success, or `NULL` on failure.
 */
gigastt_ struct GigasttGigasttStream *gigastt_stream_new(struct GigasttGigasttEngine *engine);

/**
 * Process a chunk of PCM16 audio and return any partial/final segments.
 *
 * # Safety
 * - `engine` and `stream` must be valid pointers.
 * - `pcm16_bytes` must point to at least `len` valid bytes (little-endian mono PCM16).
 * - NOT thread-safe (single-threaded-per-handle): no thread may call
 *   `gigastt_engine_free`/`gigastt_stream_free` on these pointers concurrently
 *   with this call. The early `disposed` check rejects already-freed handles but
 *   does not close the in-call race.
 *
 * Returns a newly allocated JSON array string on success, or `NULL` on failure.
 * The caller **must** free the returned string with `gigastt_string_free`.
 */
gigastt_
char *gigastt_stream_process_chunk(struct GigasttGigasttEngine *engine,
                                   struct GigasttGigasttStream *stream,
                                   const uint8_t *pcm16_bytes,
                                   uintptr_t len,
                                   uint32_t sample_rate);

/**
 * Flush the streaming state and return the final segment(s).
 *
 * # Safety
 * `engine` and `stream` must be valid pointers. NOT thread-safe
 * (single-threaded-per-handle): no thread may call `gigastt_engine_free`/
 * `gigastt_stream_free` on these pointers concurrently with this call. The early
 * `disposed` check rejects already-freed handles but does not close the in-call race.
 *
 * Returns a newly allocated JSON array string (possibly `[]`) on success,
 * or `NULL` on failure. The caller **must** free the returned string with
 * `gigastt_string_free`.
 */
gigastt_
char *gigastt_stream_flush(struct GigasttGigasttEngine *engine,
                           struct GigasttGigasttStream *stream);

/**
 * Free a streaming session and return its triplet to the pool.
 *
 * # Safety
 * `stream` must be a pointer returned by `gigastt_stream_new` and not yet freed,
 * or `NULL` (in which case this is a no-op). NOT thread-safe
 * (single-threaded-per-handle): the caller must ensure no other call using this
 * pointer runs concurrently with this free.
 */
gigastt_ void gigastt_stream_free(struct GigasttGigasttStream *stream);

#endif  /* GIGASTT_H */
