// gpu_device.cpp - Implementació del wrapper de SDL_GPUDevice

#include "core/rendering/gpu/gpu_device.hpp"

#include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>

#include <iostream>

namespace Rendering::GPU {

    GpuDevice::~GpuDevice() { destroy(); }

    auto GpuDevice::init(SDL_Window* window) -> bool {
        window_ = window;

        // Selecció del format de shader per plataforma:
        //  - macOS  → MSL (Metal Shading Language), shaders embedits a gpu/msl/*.msl.h
        //  - Resta  → SPIR-V (Vulkan), shaders embedits a gpu/spv/*.h
#ifdef __APPLE__
        constexpr SDL_GPUShaderFormat SHADER_FORMATS = SDL_GPU_SHADERFORMAT_MSL;
#else
        constexpr SDL_GPUShaderFormat SHADER_FORMATS = SDL_GPU_SHADERFORMAT_SPIRV;
#endif

        device_ = SDL_CreateGPUDevice(SHADER_FORMATS, /*debug_mode=*/true, /*name=*/nullptr);
        if (device_ == nullptr) {
            std::cerr << "[GpuDevice] SDL_CreateGPUDevice falló: " << SDL_GetError() << '\n';
            return false;
        }

        const char* driver = SDL_GetGPUDeviceDriver(device_);
        std::cout << "[GpuDevice] Backend GPU: " << (driver != nullptr ? driver : "?") << '\n';

        if (!SDL_ClaimWindowForGPUDevice(device_, window_)) {
            std::cerr << "[GpuDevice] SDL_ClaimWindowForGPUDevice falló: " << SDL_GetError() << '\n';
            SDL_DestroyGPUDevice(device_);
            device_ = nullptr;
            return false;
        }

        swapchain_format_ = SDL_GetGPUSwapchainTextureFormat(device_, window_);
        return true;
    }

    void GpuDevice::destroy() {
        if (device_ != nullptr) {
            if (window_ != nullptr) {
                SDL_ReleaseWindowFromGPUDevice(device_, window_);
            }
            SDL_DestroyGPUDevice(device_);
            device_ = nullptr;
        }
        window_ = nullptr;
        swapchain_format_ = SDL_GPU_TEXTUREFORMAT_INVALID;
    }

}  // namespace Rendering::GPU
