#include <renderer/backend_api.h>
#include <runtime/runtime.h>
#include <runtime/config.h>

#include "device.h"

extern rt_cvar r_VkEnableAPIAllocTracking;
extern rt_cvar r_VkPhysDeviceName;
extern rt_cvar r_VkMaxFramesInFlight;
extern rt_cvar r_VkPreferMailboxMode;
extern rt_cvar r_VkPreferRelaxedMode;
extern rt_cvar r_VkEnableVSync;
extern rt_cvar r_VkMaxResources;
extern rt_cvar r_VkBindlessUniformBufferDescriptors;
extern rt_cvar r_VkBindlessStorageBufferDescriptors;
extern rt_cvar r_VkBindlessSampledImageDescriptors;
extern rt_cvar r_VkBindlessStorageImageDescriptors;
extern rt_cvar r_VkBindlessSamplerDescriptors;

void VkRegisterCVARs(void) {
    rtRegisterCVAR(&r_VkEnableAPIAllocTracking);
    rtRegisterCVAR(&r_VkPhysDeviceName);
    rtRegisterCVAR(&r_VkMaxFramesInFlight);
    rtRegisterCVAR(&r_VkPreferMailboxMode);
    rtRegisterCVAR(&r_VkPreferRelaxedMode);
    rtRegisterCVAR(&r_VkEnableVSync);
    rtRegisterCVAR(&r_VkMaxResources);
    rtRegisterCVAR(&r_VkBindlessUniformBufferDescriptors);
    rtRegisterCVAR(&r_VkBindlessStorageBufferDescriptors);
    rtRegisterCVAR(&r_VkBindlessSampledImageDescriptors);
    rtRegisterCVAR(&r_VkBindlessStorageImageDescriptors);
    rtRegisterCVAR(&r_VkBindlessSamplerDescriptors);
}

static rt_vk_device _device;

rt_render_backend_init_result VkInit(const rt_renderer_window_info *info) {
    rt_render_backend_init_result res = {.result = RT_SUCCESS};

    rt_create_vk_device_result device_result = rtCreateVkDevice(info);
    if (device_result.result != RT_SUCCESS) {
        res.result = device_result.result;
        return res;
    }
    /* Populate the device interface */
    _device = device_result.device;
    rt_render_device_i device_i = {
        .o =  &_device,
        .GetPhysicalResourceManager = rtVkDevGetPhysicalResourceManager,
        .SubmitCommandList = rtVkDevSubmitCommandList,
    };
    res.device = device_i;

    return res;
}

void VkShutdown(void) {
    rtDestroyVkDevice(&_device);
}

// Called by the application to retrieve the renderer api
RT_DLLEXPORT rt_render_backend_api rtLoadRenderBackendImpl(void) {
    rt_render_backend_api api = {
        .RegisterCVARs = VkRegisterCVARs,
        .Init          = VkInit,
        .Shutdown      = VkShutdown,
    };
    return api;
}
