/*
 * Copyright 2023 Rive
 */

#include "rive/renderer/vulkan/vkutil.hpp"

#include "rive/rive_types.hpp"
#include "rive/renderer/vulkan/vulkan_context.hpp"
#include <vk_mem_alloc.h>

namespace rive::gpu::vkutil
{
#define STR_CASE(result)                                                       \
    case VK_##result:                                                          \
        return #result

const char* string_from_vk_result(VkResult result)
{
    switch (result)
    {
        STR_CASE(SUCCESS);
        STR_CASE(NOT_READY);
        STR_CASE(TIMEOUT);
        STR_CASE(EVENT_SET);
        STR_CASE(EVENT_RESET);
        STR_CASE(INCOMPLETE);
        STR_CASE(ERROR_OUT_OF_HOST_MEMORY);
        STR_CASE(ERROR_OUT_OF_DEVICE_MEMORY);
        STR_CASE(ERROR_INITIALIZATION_FAILED);
        STR_CASE(ERROR_DEVICE_LOST);
        STR_CASE(ERROR_MEMORY_MAP_FAILED);
        STR_CASE(ERROR_LAYER_NOT_PRESENT);
        STR_CASE(ERROR_EXTENSION_NOT_PRESENT);
        STR_CASE(ERROR_FEATURE_NOT_PRESENT);
        STR_CASE(ERROR_INCOMPATIBLE_DRIVER);
        STR_CASE(ERROR_TOO_MANY_OBJECTS);
        STR_CASE(ERROR_FORMAT_NOT_SUPPORTED);
        STR_CASE(ERROR_SURFACE_LOST_KHR);
        STR_CASE(SUBOPTIMAL_KHR);
        STR_CASE(ERROR_OUT_OF_DATE_KHR);
        STR_CASE(ERROR_INCOMPATIBLE_DISPLAY_KHR);
        STR_CASE(ERROR_NATIVE_WINDOW_IN_USE_KHR);
        STR_CASE(ERROR_VALIDATION_FAILED_EXT);
        STR_CASE(ERROR_OUT_OF_POOL_MEMORY);
        default:
            return "<unknown>";
    }
}
Resource::Resource(rcp<VulkanContext> vk) : GPUResource(std::move(vk)) {}

VulkanContext* Resource::vk() const
{
    return static_cast<VulkanContext*>(m_manager.get());
}

Buffer::Buffer(rcp<VulkanContext> vk,
               const VkBufferCreateInfo& info,
               Mappability mappability) :
    Resource(std::move(vk)), m_mappability(mappability), m_info(info)
{
    m_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    init();
}

Buffer::~Buffer() { resizeImmediately(0); }

void Buffer::resizeImmediately(VkDeviceSize sizeInBytes)
{
    if (m_info.size != sizeInBytes)
    {
        if (m_vmaAllocation != VK_NULL_HANDLE)
        {
            if (m_mappability != Mappability::none)
            {
                vmaUnmapMemory(vk()->allocator(), m_vmaAllocation);
            }
            vmaDestroyBuffer(vk()->allocator(), m_vkBuffer, m_vmaAllocation);
        }
        m_info.size = sizeInBytes;
        init();
    }
}

VmaAllocationCreateFlags vma_flags_for_mappability(Mappability mappability)
{
    switch (mappability)
    {
        case Mappability::none:
            return 0;
        case Mappability::writeOnly:
            return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
        case Mappability::readWrite:
            return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
    }
    RIVE_UNREACHABLE();
}

void Buffer::init()
{
    // Cleared up front so a failed allocation leaves nothing for ~Buffer() to
    // free; vmaCreateBuffer() doesn't define its outputs when it fails.
    m_vkBuffer = VK_NULL_HANDLE;
    m_vmaAllocation = VK_NULL_HANDLE;
    m_contents = nullptr;

    if (m_info.size > 0)
    {
        VmaAllocationCreateInfo allocInfo = {
            .flags = vma_flags_for_mappability(m_mappability),
            .usage = VMA_MEMORY_USAGE_AUTO,
        };

        VkBuffer buffer;
        VmaAllocation allocation;
        if (!VK_SUCCEEDED(vmaCreateBuffer(vk()->allocator(),
                                          &m_info,
                                          &allocInfo,
                                          &buffer,
                                          &allocation,
                                          nullptr),
                          "a buffer"))
        {
            vk()->reportAllocationFailure();
            return;
        }
        m_vkBuffer = buffer;
        m_vmaAllocation = allocation;

        if (m_mappability != Mappability::none)
        {
            // Leave the buffer constantly mapped and let the OS/drivers handle
            // the rest.
            void* contents;
            if (!VK_SUCCEEDED(
                    vmaMapMemory(vk()->allocator(), m_vmaAllocation, &contents),
                    "a buffer mapping"))
            {
                // Throw the buffer away too. A mappable buffer we can't map is
                // useless, and callers test the handle to decide whether we
                // allocated anything at all.
                vmaDestroyBuffer(vk()->allocator(),
                                 m_vkBuffer,
                                 m_vmaAllocation);
                m_vkBuffer = VK_NULL_HANDLE;
                m_vmaAllocation = VK_NULL_HANDLE;
                vk()->reportAllocationFailure();
                return;
            }
            m_contents = contents;
        }
    }
}

void Buffer::flushContents(VkDeviceSize updatedSizeInBytes)
{
    vmaFlushAllocation(vk()->allocator(),
                       m_vmaAllocation,
                       0,
                       updatedSizeInBytes);
}

void Buffer::invalidateContents(VkDeviceSize updatedSizeInBytes)
{
    vmaInvalidateAllocation(vk()->allocator(),
                            m_vmaAllocation,
                            0,
                            updatedSizeInBytes);
}

BufferPool::BufferPool(rcp<VulkanContext> vk,
                       VkBufferUsageFlags usageFlags,
                       VkDeviceSize size) :
    GPUResourcePool(std::move(vk), MAX_POOL_SIZE),
    m_usageFlags(usageFlags),
    m_targetSize(size)
{}

inline VulkanContext* BufferPool::vk() const
{
    return static_cast<VulkanContext*>(m_manager.get());
}

void BufferPool::setTargetSize(VkDeviceSize size)
{
    // Buffers always get bound, even if unused, so make sure they aren't empty
    // and we get a valid Vulkan handle.
    size = std::max<VkDeviceSize>(size, 1);

    if (m_usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
    {
        // Uniform blocks must be multiples of 256 bytes in size.
        size = std::max<VkDeviceSize>(size, 256);
        assert(size % 256 == 0);
    }

    m_targetSize = size;
}

rcp<vkutil::Buffer> BufferPool::acquire()
{
    auto buffer = static_rcp_cast<vkutil::Buffer>(GPUResourcePool::acquire());
    if (buffer == nullptr)
    {
        buffer = vk()->makeBuffer(
            {
                .size = m_targetSize,
                .usage = m_usageFlags,
            },
            Mappability::writeOnly);
    }
    else if (buffer->info().size != m_targetSize)
    {
        buffer->resizeImmediately(m_targetSize);
    }
    return buffer;
}

Image::Image(rcp<VulkanContext> vulkanContext,
             const VkImageCreateInfo& info,
             const char* name) :
    Resource(std::move(vulkanContext)), m_info(info)
{
    m_info = info;
    m_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;

    if (m_info.mipLevels == 0)
    {
        m_info.mipLevels = 1;
    }
    else if (m_info.mipLevels > 1)
    {
        // We generate mipmaps internally with image blits.
        m_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    }

    if (m_info.arrayLayers == 0)
    {
        m_info.arrayLayers = 1;
    }

    if (m_info.samples == 0)
    {
        m_info.samples = VK_SAMPLE_COUNT_1_BIT;
    }

    if (m_info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)
    {
        // Attempt to create transient attachments with lazily-allocated memory.
        // This should succeed on mobile. Otherwise, use normal memory.
        VmaAllocationCreateInfo allocInfo = {
            .usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED,
        };

        if (vmaCreateImage(vk()->allocator(),
                           &m_info,
                           &allocInfo,
                           &m_vkImage,
                           &m_vmaAllocation,
                           nullptr) == VK_SUCCESS)
        {
            vk()->setDebugNameIfEnabled(uint64_t(m_vkImage),
                                        VK_OBJECT_TYPE_IMAGE,
                                        name);
            return;
        }
    }

    VmaAllocationCreateInfo allocInfo = {
        .usage = VMA_MEMORY_USAGE_AUTO,
    };

    VkImage image;
    VmaAllocation allocation;
    if (!VK_SUCCEEDED(vmaCreateImage(vk()->allocator(),
                                     &m_info,
                                     &allocInfo,
                                     &image,
                                     &allocation,
                                     nullptr),
                      name))
    {
        vk()->reportAllocationFailure();
        return;
    }
    m_vkImage = image;
    m_vmaAllocation = allocation;
    vk()->setDebugNameIfEnabled(uint64_t(m_vkImage),
                                VK_OBJECT_TYPE_IMAGE,
                                name);
}

Image::Image(rcp<VulkanContext> vulkanContext,
             VkImage externalImage,
             const VkImageCreateInfo& info,
             const char* name) :
    Resource(std::move(vulkanContext)), m_info(info)
{
    m_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    m_vkImage = externalImage;
    vk()->setDebugNameIfEnabled(uint64_t(m_vkImage),
                                VK_OBJECT_TYPE_IMAGE,
                                name);
}

Image::~Image()
{
    if (m_vmaAllocation != VK_NULL_HANDLE)
    {
        vmaDestroyImage(vk()->allocator(), m_vkImage, m_vmaAllocation);
    }
}

ImageView::ImageView(rcp<VulkanContext> vulkanContext,
                     rcp<Image> textureRef,
                     const VkImageViewCreateInfo& info,
                     const char* name) :
    Resource(std::move(vulkanContext)),
    m_textureRefOrNull(std::move(textureRef)),
    m_info(info)
{
    if (m_info.image == VK_NULL_HANDLE)
    {
        assert(m_textureRefOrNull != nullptr);
        m_info.image = *m_textureRefOrNull;
    }
    else
    {
        assert(m_textureRefOrNull == nullptr ||
               m_info.image == *m_textureRefOrNull);
    }
    if (m_info.image == VK_NULL_HANDLE)
    {
        // The image we're viewing failed to allocate. Stay null as well.
        return;
    }

    m_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    m_vkImageView = VK_CREATE_HANDLE(vk(), CreateImageView, &m_info);
    vk()->setDebugNameIfEnabled(uint64_t(m_vkImageView),
                                VK_OBJECT_TYPE_IMAGE_VIEW,
                                name);
}

ImageView::~ImageView()
{
    vk()->DestroyImageView(vk()->device, m_vkImageView, nullptr);
}

Texture2D::Texture2D(rcp<VulkanContext> vk,
                     VkImageCreateInfo info,
                     const char* name) :
    rive::gpu::Texture(info.extent.width, info.extent.height),
    m_lastAccess({
        .pipelineStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
        .accessMask = VK_ACCESS_NONE,
        .layout = VK_IMAGE_LAYOUT_UNDEFINED,
    })
{
    assert(info.imageType == 0 || info.imageType == VK_IMAGE_TYPE_2D);
    if (info.imageType == 0)
    {
        info.imageType = VK_IMAGE_TYPE_2D;
    }
    if (info.extent.depth == 0)
    {
        info.extent.depth = 1;
    }
    if (info.usage == 0)
    {
        info.usage =
            VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    }
    m_image = vk->makeImage(info, name);
    m_imageView = vk->makeImageView(m_image, name);
}

Texture2D::Texture2D(rcp<VulkanContext> vk,
                     rcp<Image> existingImage,
                     const char* name) :
    rive::gpu::Texture(existingImage->info().extent.width,
                       existingImage->info().extent.height),
    m_image(std::move(existingImage)),
    m_lastAccess({
        .pipelineStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
        .accessMask = VK_ACCESS_NONE,
        .layout = VK_IMAGE_LAYOUT_UNDEFINED,
    })
{
    m_imageView = vk->makeImageView(m_image, name);
}

void Texture2D::scheduleUpload(const void* imageDataRGBAPremul,
                               size_t imageDataSizeInBytes)
{
    rcp<vkutil::Buffer> imageBufferRGBAPremul = m_image->vk()->makeBuffer(
        {
            .size = imageDataSizeInBytes,
            .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
        },
        vkutil::Mappability::writeOnly);
    if (!imageBufferRGBAPremul->hasContents())
    {
        // Nothing to upload into; the init path that owns us will bail shortly.
        return;
    }
    memcpy(imageBufferRGBAPremul->contents(),
           imageDataRGBAPremul,
           imageDataSizeInBytes);
    imageBufferRGBAPremul->flushContents();
    scheduleUpload(std::move(imageBufferRGBAPremul));
}

void Texture2D::scheduleUpload(rcp<vkutil::Buffer> imageBufferRGBAPremul)
{
    m_imageUploadBuffer = std::move(imageBufferRGBAPremul);
    m_imageUploadRegions.clear();
}

void Texture2D::scheduleUpload(rcp<vkutil::Buffer> stagingBuffer,
                               std::vector<VkBufferImageCopy> regions)
{
    m_imageUploadBuffer = std::move(stagingBuffer);
    m_imageUploadRegions = std::move(regions);
}

void Texture2D::applyImageUploadBuffer(VkCommandBuffer commandBuffer)
{
    assert(m_imageUploadBuffer != nullptr);

    barrier(commandBuffer,
            {
                .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
                .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
                .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            },
            vkutil::ImageAccessAction::invalidateContents);

    if (!m_imageUploadRegions.empty())
    {
        // Caller-supplied per-level regions. No automatic mip generation —
        // every level present in the texture must have a region.
        m_image->vk()->CmdCopyBufferToImage(
            commandBuffer,
            *m_imageUploadBuffer,
            *m_image,
            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            static_cast<uint32_t>(m_imageUploadRegions.size()),
            m_imageUploadRegions.data());
        // All mips already written — transition straight to shader-read.
        barrier(commandBuffer,
                {
                    .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
                    .accessMask = VK_ACCESS_SHADER_READ_BIT,
                    .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                });
        m_imageUploadRegions.clear();
    }
    else
    {
        // Single-region upload (mip 0 full extent). Caller relies on
        // generateMipmaps to fill remaining levels.
        VkBufferImageCopy bufferImageCopy = {
            .imageSubresource =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .layerCount = 1,
                },
            .imageExtent = {width(), height(), 1},
        };
        m_image->vk()->CmdCopyBufferToImage(
            commandBuffer,
            *m_imageUploadBuffer,
            *m_image,
            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            1,
            &bufferImageCopy);
        generateMipmaps(
            commandBuffer,
            {
                .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
                .accessMask = VK_ACCESS_SHADER_READ_BIT,
                .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
            });
    }

    m_imageUploadBuffer = nullptr;
}

void Texture2D::barrier(VkCommandBuffer commandBuffer,
                        const vkutil::ImageAccess& dstAccess,
                        vkutil::ImageAccessAction imageAccessAction,
                        VkDependencyFlags dependencyFlags)
{
    // Always perform the barrier, even if m_lastAccess == dstAccess, because
    // a pipeline barrier may still be needed even if we aren't transitioning
    // the image or interacting with other stages.
    m_lastAccess = m_image->vk()->simpleImageMemoryBarrier(commandBuffer,
                                                           m_lastAccess,
                                                           dstAccess,
                                                           *m_image,
                                                           imageAccessAction,
                                                           dependencyFlags);
}

void Texture2D::generateMipmaps(VkCommandBuffer commandBuffer,
                                const ImageAccess& dstAccess)
{
    VulkanContext* vk = m_image->vk();
    uint32_t mipLevels = m_image->info().mipLevels;
    if (mipLevels <= 1)
    {
        barrier(commandBuffer, dstAccess);
        return;
    }

    barrier(commandBuffer,
            {
                .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT,
                .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
                .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            });

    int2 dstSize, srcSize = {static_cast<int32_t>(width()),
                             static_cast<int32_t>(height())};
    for (uint32_t level = 1; level < mipLevels; ++level, srcSize = dstSize)
    {
        dstSize = simd::max(srcSize >> 1, int2(1));

        VkImageBlit imageBlit = {
            .srcSubresource =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .mipLevel = level - 1,
                    .layerCount = 1,
                },
            .dstSubresource =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .mipLevel = level,
                    .layerCount = 1,
                },
        };

        imageBlit.srcOffsets[0] = {0, 0, 0};
        imageBlit.srcOffsets[1] = {srcSize.x, srcSize.y, 1};

        imageBlit.dstOffsets[0] = {0, 0, 0};
        imageBlit.dstOffsets[1] = {dstSize.x, dstSize.y, 1};

        vk->imageMemoryBarrier(
            commandBuffer,
            VK_PIPELINE_STAGE_TRANSFER_BIT,
            VK_PIPELINE_STAGE_TRANSFER_BIT,
            0,
            {
                .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
                .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
                .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                .image = *m_image,
                .subresourceRange =
                    {
                        .baseMipLevel = level - 1,
                        .levelCount = 1,
                    },
            });

        vk->CmdBlitImage(commandBuffer,
                         *m_image,
                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                         *m_image,
                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                         1,
                         &imageBlit,
                         VK_FILTER_LINEAR);
    }

    VkImageMemoryBarrier barriers[] = {
        {
            // The first N - 1 layers are in TRANSFER_READ.
            .srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
            .dstAccessMask = dstAccess.accessMask,
            .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
            .newLayout = dstAccess.layout,
            .image = *m_image,
            .subresourceRange =
                {
                    .baseMipLevel = 0,
                    .levelCount = mipLevels - 1,
                },
        },
        {
            // The final layer is still in TRANSFER_WRITE.
            .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
            .dstAccessMask = dstAccess.accessMask,
            .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            .newLayout = dstAccess.layout,
            .image = *m_image,
            .subresourceRange =
                {
                    .baseMipLevel = mipLevels - 1,
                    .levelCount = 1,
                },
        },
    };

    vk->imageMemoryBarriers(commandBuffer,
                            VK_PIPELINE_STAGE_TRANSFER_BIT,
                            dstAccess.pipelineStages,
                            0,
                            std::size(barriers),
                            barriers);

    m_lastAccess = dstAccess;
}

Framebuffer::Framebuffer(rcp<VulkanContext> vulkanContext,
                         const VkFramebufferCreateInfo& info) :
    Resource(std::move(vulkanContext)), m_info(info)
{
    m_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    m_vkFramebuffer = VK_CREATE_HANDLE(vk(), CreateFramebuffer, &m_info);
}

Framebuffer::~Framebuffer()
{
    vk()->DestroyFramebuffer(vk()->device, m_vkFramebuffer, nullptr);
}
} // namespace rive::gpu::vkutil
