#pragma once
#include <cuda_runtime.h>
#include <iostream>

#ifdef ENABLE_OPTIX
#include <optix.h>
#include <optix_host.h>


static void context_log_cb(unsigned int level, const char* tag, const char* message, void*) {
    fprintf(stderr, "[%2d][%12s]: %s\n", (int) level, tag, message);
}

inline void checkOptixError(OptixResult error) {
    if (error != OPTIX_SUCCESS) {
        std::cerr << "Optix call failed: " << optixGetErrorString(error) << std::endl;
    }
}

class Denoiser {
public:
    Denoiser();
    ~Denoiser();

    void denoiseTexture(cudaSurfaceObject_t surface, float4* data, unsigned int width, unsigned int height);

private:
    cudaStream_t stream = nullptr;
    OptixDeviceContext optixContext = nullptr;
    OptixDenoiser denoiser = nullptr;

    unsigned int m_scratch_size = 0;
    unsigned int m_state_size = 0;
    CUdeviceptr m_scratch = 0;
    CUdeviceptr m_state = 0;

    OptixDenoiserParams m_params = {0, 0.0f, 0, 0};
};

#endif