#include "shader_compiler.h"

#ifdef RT_BUILD_DXC_SHADER_COMPILER
extern rt_shader_bytecode CompileVulkanShader(rt_shader_stage stage,
                                              rt_shader_optimization_level optimization,
                                              rt_text_span code,
                                              const char *file_path,
                                              rt_arena *arena);
#endif

#ifdef RT_BUILD_DX11_SHADER_COMPILER
extern rt_shader_bytecode CompileDX11Shader(rt_shader_stage stage,
                                            rt_shader_optimization_level optimization,
                                            rt_text_span code,
                                            const char *file_path,
                                            rt_arena *arena);
#endif

static rt_shader_bytecode CompileNullShader(rt_shader_stage stage,
                                            rt_shader_optimization_level optimization,
                                            rt_text_span code,
                                            const char *file_path,
                                            rt_arena *arena) {
    RT_UNUSED(stage);
    RT_UNUSED(optimization);
    RT_UNUSED(code);
    RT_UNUSED(arena);
    rtLog("AC", "Attempted to compile shader %s with unsupported type.", file_path);
    return (rt_shader_bytecode){
        .bytes = NULL,
        .len   = 0,
    };
}

typedef rt_shader_bytecode shader_compiler_fn(rt_shader_stage,
                                              rt_shader_optimization_level,
                                              rt_text_span,
                                              const char *,
                                              rt_arena *);

static shader_compiler_fn *_compiler_funcs[RT_SHADER_TYPE_count] = {
    CompileNullShader,

#ifdef RT_BUILD_DXC_SHADER_COMPILER
    CompileVulkanShader,
#else
    CompileNullShader,
#endif

#ifdef RT_BUILD_DX11_SHADER_COMPILER
    CompileDX11Shader,
#else
    CompileNullShader,
#endif
};

rt_shader_bytecode CompileShader(rt_shader_type type,
                                 rt_shader_stage stage,
                                 rt_shader_optimization_level optimization,
                                 rt_text_span code,
                                 const char *file_path,
                                 rt_arena *arena) {
    if (type >= RT_SHADER_TYPE_count) {
        rtLog("AC", "Invalid shader type %u", type);
        return (rt_shader_bytecode){.bytes = NULL, .len = 0};
    }
    return _compiler_funcs[type](stage, optimization, code, file_path, arena);
}
