# compile_spirv.cmake
# Compila shaders GLSL a SPIR-V y genera headers C++ embebibles.
# Multiplataforma: Windows, macOS, Linux (no requiere bash, xxd ni /tmp/).
#
# Invocado por CMakeLists.txt con:
#   cmake -D GLSLC=<path> -D SHADERS_DIR=<path> -D HEADERS_DIR=<path> -P compile_spirv.cmake
#
# También puede ejecutarse manualmente desde la raíz del proyecto:
#   cmake -D GLSLC=glslc -D SHADERS_DIR=data/shaders -D HEADERS_DIR=source/core/rendering/sdl3gpu -P tools/shaders/compile_spirv.cmake

cmake_minimum_required(VERSION 3.10)
cmake_policy(SET CMP0007 NEW)

# Lista de shaders: fuente relativa a SHADERS_DIR
set(SHADER_SOURCES
    "postfx.vert"
    "postfx.frag"
    "upscale.frag"
    "downscale.frag"
    "crtpi_frag.glsl"
)

# Nombre de la variable C++ para cada shader (mismo orden)
set(SHADER_VARS
    "kpostfx_vert_spv"
    "kpostfx_frag_spv"
    "kupscale_frag_spv"
    "kdownscale_frag_spv"
    "kcrtpi_frag_spv"
)

# Flags extra de glslc para cada shader (vacío si no hay)
set(SHADER_FLAGS
    ""
    ""
    ""
    ""
    "-fshader-stage=frag"
)

list(LENGTH SHADER_SOURCES NUM_SHADERS)
math(EXPR LAST_IDX "${NUM_SHADERS} - 1")

foreach(IDX RANGE ${LAST_IDX})
    list(GET SHADER_SOURCES ${IDX} SRC_NAME)
    list(GET SHADER_VARS    ${IDX} VAR)
    list(GET SHADER_FLAGS   ${IDX} EXTRA_FLAG)

    # Derivar nombre del header desde la variable: kpostfx_vert_spv → postfx_vert_spv.h
    string(REGEX REPLACE "^k" "" HDR_BASE "${VAR}")
    set(SRC "${SHADERS_DIR}/${SRC_NAME}")
    set(SPV "${HEADERS_DIR}/${HDR_BASE}.spv")
    set(HDR "${HEADERS_DIR}/${HDR_BASE}.h")

    message(STATUS "Compilando ${SRC} ...")

    if(EXTRA_FLAG)
        execute_process(
            COMMAND "${GLSLC}" "${EXTRA_FLAG}" "${SRC}" -o "${SPV}"
            RESULT_VARIABLE GLSLC_RESULT
            ERROR_VARIABLE  GLSLC_ERROR
        )
    else()
        execute_process(
            COMMAND "${GLSLC}" "${SRC}" -o "${SPV}"
            RESULT_VARIABLE GLSLC_RESULT
            ERROR_VARIABLE  GLSLC_ERROR
        )
    endif()

    if(NOT GLSLC_RESULT EQUAL 0)
        message(FATAL_ERROR "glslc falló para ${SRC}:\n${GLSLC_ERROR}")
    endif()

    # Leer binario SPV como hex (sin separadores: "0302230700...")
    file(READ "${SPV}" HEX_DATA HEX)
    # Dividir en pares de caracteres hex → lista de bytes
    string(REGEX MATCHALL ".." BYTES "${HEX_DATA}")
    list(LENGTH BYTES NUM_BYTES)

    # Construir el cuerpo del array C++ con un byte por línea
    set(ARRAY_BODY "")
    foreach(BYTE ${BYTES})
        string(APPEND ARRAY_BODY "    0x${BYTE},\n")
    endforeach()

    file(WRITE "${HDR}"
        "#pragma once\n"
        "#include <cstddef>\n"
        "#include <cstdint>\n"
        "static const uint8_t ${VAR}[] = {\n"
        "${ARRAY_BODY}"
        "};\n"
        "static const size_t ${VAR}_size = ${NUM_BYTES};\n"
    )

    file(REMOVE "${SPV}")
    message(STATUS "  -> ${HDR} (${NUM_BYTES} bytes)")
endforeach()

message(STATUS "Shaders SPIR-V compilados correctamente.")
