#ifndef SCULBLOG_FFI_H
#define SCULBLOG_FFI_H

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

// Forward declare the opaque DtobValue struct from libdtob
typedef struct DtobValue DtobValue;

void ffi_bromberg_init(void);
void ffi_bromberg_hash(const uint8_t* in, size_t len, uint8_t out[32]);

void ffi_diff_build(const uint8_t *old_data, size_t old_len, const uint8_t *new_data, size_t new_len, DtobValue *diff);
uint8_t* ffi_apply_diff(const uint8_t *prev, size_t prev_len, const DtobValue *diff_val, size_t *out_len);

DtobValue* ffi_array_new(void);
DtobValue* ffi_kvset_new(void);
void ffi_array_push(DtobValue* arr, DtobValue* val);
void ffi_kvset_put(DtobValue* kv, const char* key, DtobValue* val);
DtobValue* ffi_kvset_get(DtobValue* kv, const char* key);
DtobValue* ffi_raw_new(const uint8_t* data, size_t len);
DtobValue* ffi_uint_new(uint64_t val);

DtobValue* ffi_dif_ops_new(void);
void ffi_dif_ops_push_add(DtobValue* diff, const uint8_t* data, size_t len);

DtobValue* ffi_build_dif_entry(
    DtobValue* ops
);

uint8_t* ffi_encode_xanadoc_header(DtobValue* root, size_t *out_len);
DtobValue* ffi_xanadoc_ids_new(const uint8_t* ccid, const uint8_t* cid, const uint8_t* sha256);

uint8_t* ffi_encode_dif(DtobValue* root, size_t *out_len);
uint8_t* ffi_encode_chunk(DtobValue* val, size_t *out_len);
int ffi_verify_file_types(const char* path, int strict);
DtobValue* ffi_decode_dif(const uint8_t* buf, size_t len);
void ffi_dtob_free(DtobValue* val);

size_t ffi_dtob_array_len(const DtobValue* val);
const DtobValue* ffi_dtob_array_get(const DtobValue* val, size_t idx);

size_t ffi_dtob_kvset_len(const DtobValue* val);
const char* ffi_dtob_kvset_key(const DtobValue* val, size_t idx);
const DtobValue* ffi_dtob_kvset_value_at(const DtobValue* val, size_t idx);

const uint8_t* ffi_dtob_get_raw(const DtobValue* val, size_t* out_len);
uint64_t ffi_dtob_get_u64(const DtobValue* val);

// xanadoc (.xdc) reading
uint8_t* ffi_xdc_decode_content(const uint8_t* data, size_t len, size_t* out_len);
uint8_t* ffi_xdc_decode_references(const uint8_t* data, size_t len, size_t* out_len);

#endif // SCULBLOG_FFI_H
