package net.halbear.Terrain4J.EngineCore.Profiling;

import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.*;

import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.List;

import static org.lwjgl.vulkan.EXTMemoryBudget.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
import static org.lwjgl.vulkan.VK13.*;

public class GPUProfiler {

    private static String VramCapacity = "";
    public static String GetVramCapacity(){return VramCapacity;}

    public static List<String[]> GetVramUsage(VkPhysicalDevice physicalDevice){
        List<String[]> result = new ArrayList<>();
        try(var MemStack = MemoryStack.stackPush()){
            VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget =
                    VkPhysicalDeviceMemoryBudgetPropertiesEXT.calloc(MemStack)
                            .sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT);
            VkPhysicalDeviceMemoryProperties2 MemoryProperties2 = VkPhysicalDeviceMemoryProperties2.calloc(MemStack)
                    .sType(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2)
                    .pNext(memoryBudget.address());
            vkGetPhysicalDeviceMemoryProperties2(physicalDevice,MemoryProperties2);

            VkPhysicalDeviceMemoryProperties MemoryProperties = MemoryProperties2.memoryProperties();
            int HeapCount = MemoryProperties.memoryHeapCount();
            for(int i = 0; i < HeapCount; i++){
                VkMemoryHeap heap = MemoryProperties.memoryHeaps(i);
                if ((heap.flags() & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) {
                    long AllocatedByProcess = memoryBudget.heapUsage(i);
                    long OverallSystemBudget = memoryBudget.heapBudget(i);
                    long TotalHeapSize = heap.size();
                    String[] properties = new String[5];
                    VramCapacity = String.format(" %.2f GB\n",TotalHeapSize / (1024.0 * 1024.0*1024.0));
                    properties[0] = String.format("VIDEO MEMORY USAGE METRICS:\n");
                    properties[1] = String.format("VRAM Heap %d :", i);
                    properties[2] = String.format("  Total Capacity: %.2f MB\n", TotalHeapSize / (1024.0 * 1024.0));
                    properties[3] = String.format("  Terrain4J Usage:  %.2f MB\n", AllocatedByProcess / (1024.0 * 1024.0));
                    properties[4] = String.format("  System Budget: %.2f MB\n", OverallSystemBudget / (1024.0 * 1024.0));
                    result.add(properties);
                }
            }
        }
        return result;
    }

    private long RemoteryInstance;

    public GPUProfiler(){

    }

    public void Initiate(Device device){
        try(var MemStack = MemoryStack.stackPush()){

        }
    }

    public void reset(VkCommandBuffer CommandBuffer){
    }

    public void StartFrame(VkCommandBuffer CommandBuffer){
    }

    public void EndFrame(VkCommandBuffer CommandBuffer){
    }

    public String LogGPUUsage(Device device){
        return "";
    }

    public void CleanUp(Device device){
    }
}
