#pragma once

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

typedef struct FfiStatus { int32_t code; } FfiStatus;
typedef struct FfiString { uint8_t* ptr; size_t len; size_t cap; } FfiString;
typedef struct FfiBuf_u8 { uint8_t* ptr; size_t len; size_t cap; size_t align; } FfiBuf_u8;
typedef struct FfiError { FfiString message; } FfiError;
typedef struct BoltFFICallbackHandle { uint64_t handle; const void* vtable; } BoltFFICallbackHandle;

{% raw %}static inline bool {% endraw %}{{ prefix }}{% raw %}_atomic_u8_cas(volatile uint8_t* target, uint8_t expected, uint8_t desired) {
    return atomic_compare_exchange_strong((_Atomic uint8_t*)target, &expected, desired);
}

static inline uint64_t {% endraw %}{{ prefix }}{% raw %}_atomic_u64_exchange(volatile uint64_t* target, uint64_t value) {
    return atomic_exchange((_Atomic uint64_t*)target, value);
}

static inline bool {% endraw %}{{ prefix }}{% raw %}_atomic_u64_cas(volatile uint64_t* target, uint64_t expected, uint64_t desired) {
    return atomic_compare_exchange_strong((_Atomic uint64_t*)target, &expected, desired);
}

static inline uint64_t {% endraw %}{{ prefix }}{% raw %}_atomic_u64_load(const volatile uint64_t* target) {
    return atomic_load_explicit((const _Atomic uint64_t*)target, memory_order_acquire);
}{% endraw %}
{% if has_async %}

typedef const void* RustFutureHandle;
typedef void (*RustFutureContinuationCallback)(uint64_t callback_data, int8_t poll_result);
{%- endif %}
{% if has_streams %}

typedef void* SubscriptionHandle;
typedef void (*StreamContinuationCallback)(uint64_t callback_data, int8_t poll_result);
{%- endif %}

