#ifndef MVGAL_SHADER_TRANSLATE_H
#define MVGAL_SHADER_TRANSLATE_H

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

#include <vulkan/vulkan.h>
#include <mvgal/mvgal_types.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------------------------------------------------------ */
/*  SPIR-V cache — open-addressing hashmap keyed by code hash         */
/* ------------------------------------------------------------------ */

#define MVGAL_SPIRV_CACHE_BITS  8
#define MVGAL_SPIRV_CAPACITY    (1U << MVGAL_SPIRV_CACHE_BITS)
#define MVGAL_SPIRV_CACHE_MASK  (MVGAL_SPIRV_CAPACITY - 1U)

typedef struct mvgal_spirv_entry {
    uint64_t      hash;          /* full 64-bit hash of SPIR-V code */
    uint32_t     *code;          /* copy of SPIR-V words             */
    size_t        word_count;    /* number of uint32_t words         */
    VkShaderModule module;       /* created shader-module handle     */
    bool          occupied;
} mvgal_spirv_entry_t;

typedef struct mvgal_spirv_cache {
    mvgal_spirv_entry_t entries[MVGAL_SPIRV_CAPACITY];
    size_t              count;
} mvgal_spirv_cache_t;

void         mvgal_spirv_cache_init(mvgal_spirv_cache_t *cache);
void         mvgal_spirv_cache_destroy(mvgal_spirv_cache_t *cache);
bool         mvgal_spirv_cache_insert(mvgal_spirv_cache_t *cache,
                                      const uint32_t *code,
                                      size_t word_count,
                                      VkShaderModule module);
VkShaderModule mvgal_spirv_cache_lookup(mvgal_spirv_cache_t *cache,
                                        const uint32_t *code,
                                        size_t word_count);
uint64_t     mvgal_spirv_hash(const uint32_t *code, size_t word_count);

/* ------------------------------------------------------------------ */
/*  SPIR-V optimization backend  (Phase 2 — SPIRV-Tools + SPIRV-Cross)*/
/* ------------------------------------------------------------------ */

#ifdef MVGAL_ENABLE_SPIRV_OPT

#ifdef __cplusplus
extern "C" {
#endif

typedef enum mvgal_spirv_backend {
    MVGAL_SPIRV_BACKEND_GLSL = 0,
    MVGAL_SPIRV_BACKEND_HLSL = 1,
    MVGAL_SPIRV_BACKEND_MSL  = 2,
} mvgal_spirv_backend_t;

/* --- SPIRV-Tools optimizer --- */
void   *mvgal_spirv_opt_create(void);
void    mvgal_spirv_opt_destroy(void *ctx);
int     mvgal_spirv_optimize(void *ctx,
                             const uint32_t *spirv,
                             size_t word_count,
                             uint32_t **out_spirv,
                             size_t *out_word_count);

/* --- SPIRV-Cross decompiler --- */
char   *mvgal_spirv_decompile(const uint32_t *spirv,
                              size_t word_count,
                              mvgal_spirv_backend_t backend);

#ifdef __cplusplus
}
#endif

#endif /* MVGAL_ENABLE_SPIRV_OPT */

/* ------------------------------------------------------------------ */
/*  Vendor compiler interface  (uses mvgal_gpu_vendor from mvgal_types.h)*/
/* ------------------------------------------------------------------ */

/* Capture SPIR-V from a vkCreateShaderModule call */
void mvgal_shader_capture(mvgal_spirv_cache_t *cache,
                          const uint32_t *code,
                          size_t word_count,
                          VkShaderModule module);

/* Route shader to vendor compiler (Phase 3 — SPIRV-Tools opt + SPIRV-Cross decompile) */
int mvgal_shader_route(mvgal_vendor_t vendor,
                       const uint32_t *spirv,
                       size_t word_count,
                       uint32_t **vendor_code,
                       size_t *vendor_code_size);

#ifdef __cplusplus
}
#endif

#endif /* MVGAL_SHADER_TRANSLATE_H */
