#!/usr/bin/env python3

import ctypes
import sys
import json

def get_header_properties(header):
    return {
        'rootNodeOffset': header.rootNodeOffset,
        'aabb': {
            'min_x': header.aabb.min_x,
            'min_y': header.aabb.min_y,
            'min_z': header.aabb.min_z,
            'max_x': header.aabb.max_x,
            'max_y': header.aabb.max_y,
            'max_z': header.aabb.max_z,
        },
        'instance_flags': header.instance_flags,
        'copy_dispatch_size': list(header.copy_dispatch_size),
        'compacted_size': header.compacted_size,
        'serialization_size': header.serialization_size,
        'size': header.size,
        'instance_count': header.instance_count,
        'self_ptr': header.self_ptr,
        'enable_64b_rt': header.enable_64b_rt,
        'padding': f"{len(header.padding)} uint32_t paddings",
    }

def get_aabb_leaf_properties(node):
    return {
        'leaf_desc': {
            'shaderIndex': node.leaf_desc.shader_index_and_geom_mask & 0xFFFFFF,
            'geomMask': (node.leaf_desc.shader_index_and_geom_mask >> 24) & 0xFF,
            'geomIndex': node.leaf_desc.geometry_id_and_flags & 0xFFFFFF,
            'subType': (node.leaf_desc.geometry_id_and_flags >> 24) & 0xF,
            'reserved0': (node.leaf_desc.geometry_id_and_flags >> 28) & 0x1,
            'DisableOpacityCull': (node.leaf_desc.geometry_id_and_flags >> 29) & 0x1,
            'OpaqueGeometry': (node.leaf_desc.geometry_id_and_flags >> 30) & 0x1,
            'IgnoreRayMultiplier': (node.leaf_desc.geometry_id_and_flags >> 31) & 0x1
        },
        'DW1': node.DW1,
        'primIndex': f"{len(node.primIndex)} uint32"
    }

def get_quad_leaf_properties(node):
    return {
        'leaf_desc': {
            'shaderIndex': node.leaf_desc.shader_index_and_geom_mask & 0xFFFFFF,
            'geomMask': (node.leaf_desc.shader_index_and_geom_mask >> 24) & 0xFF,
            'geomIndex': node.leaf_desc.geometry_id_and_flags & 0xFFFFFF,
            'subType': (node.leaf_desc.geometry_id_and_flags >> 24) & 0xF,
            'reserved0': (node.leaf_desc.geometry_id_and_flags >> 28) & 0x1,
            'DisableOpacityCull': (node.leaf_desc.geometry_id_and_flags >> 29) & 0x1,
            'OpaqueGeometry': (node.leaf_desc.geometry_id_and_flags >> 30) & 0x1,
            'IgnoreRayMultiplier': (node.leaf_desc.geometry_id_and_flags >> 31) & 0x1
        },
        'prim_index0': node.prim_index0,
        'prim_index1_and_flags':{
            'primIndex1Delta': node.prim_index1_and_flags & 0xFFFF,
            'j0': (node.prim_index1_and_flags >> 16) & 0x3,
            'j1': (node.prim_index1_and_flags >> 18) & 0x3,
            'j2': (node.prim_index1_and_flags >> 20) & 0x3,
            'last': (node.prim_index1_and_flags >> 22) & 0x1,
            'pad': (node.prim_index1_and_flags >> 23) & 0x1FF
        },
        'v': [[node.v[i][j] for j in range(3)] for i in range(4)]
    }

def get_internal_node_properties(node):
    # Calculate the actual coordinates, just for visualizing and debugging
    actual_coords = []
    for i in range(6):
        # Turns out the formula is like: x = lower.x + pow(2,exp_x) * 0.xi
        xi_lower = node.lower_x[i] / 256.0  # Convert mantissa to fractional value
        xi_upper = node.upper_x[i] / 256.0  # Convert mantissa to fractional value
        yi_lower = node.lower_y[i] / 256.0  # Convert mantissa to fractional value
        yi_upper = node.upper_y[i] / 256.0  # Convert mantissa to fractional value
        zi_lower = node.lower_z[i] / 256.0  # Convert mantissa to fractional value
        zi_upper = node.upper_z[i] / 256.0  # Convert mantissa to fractional value

        x_lower = node.lower[0] + (2 ** node.exp_x) * xi_lower
        x_upper = node.lower[0] + (2 ** node.exp_x) * xi_upper
        y_lower = node.lower[1] + (2 ** node.exp_y) * yi_lower
        y_upper = node.lower[1] + (2 ** node.exp_y) * yi_upper
        z_lower = node.lower[2] + (2 ** node.exp_z) * zi_lower
        z_upper = node.lower[2] + (2 ** node.exp_z) * zi_upper

        actual_coords.append({
            'x_lower': x_lower,
            'x_upper': x_upper,
            'y_lower': y_lower,
            'y_upper': y_upper,
            'z_lower': z_lower,
            'z_upper': z_upper
        })

    return {
        'lower': list(node.lower),
        'child_offset': node.child_offset,
        'node_type': {
            'nodeType': node.node_type & 0xF,
            'subType': (node.node_type >> 4) & 0xF
        },
        'reserved': node.reserved,
        'exp_x': node.exp_x,
        'exp_y': node.exp_y,
        'exp_z': node.exp_z,
        'node_mask': node.node_mask,
        'child_data': [{
            'blockIncr': node.child_data[i].blockIncr_and_startPrim & 0x3,
            'startPrim': (node.child_data[i].blockIncr_and_startPrim >> 2) & 0xf
        } for i in range(6)],
        'lower_x': list(node.lower_x),
        'upper_x': list(node.upper_x),
        'lower_y': list(node.lower_y),
        'upper_y': list(node.upper_y),
        'lower_z': list(node.lower_z),
        'upper_z': list(node.upper_z),
        'actual_coords': actual_coords
    }

def get_instance_leaf_properties(node, enable_64b_rt):
    if enable_64b_rt:
        part0 = {
            'instanceContribution': node.part0.DW0 & 0xFFFFFF,
            'geomMask': (node.part0.DW0 >> 24) & 0xFF,
            'insFlags': node.part0.DW1 & 0xFF,
            'ComparisonMode': (node.part0.DW1 >> 8) & 0x1,
            'ComparisonValue': (node.part0.DW1 >> 9) & 0x7F,
            'pad0': (node.part0.DW1 >> 16) & 0xFF,
            'subType': (node.part0.DW1 >> 24) & 0xF,
            'pad1': (node.part0.DW1 >> 28) & 0x1,
            'DisableOpacityCull': (node.part0.DW1 >> 29) & 0x1,
            'OpaqueGeometry': (node.part0.DW1 >> 30) & 0x1,
            'IgnoreRayMultiplier': (node.part0.DW1 >> 31) & 0x1,
            'startNodePtr': node.part0.QW_startNodePtr,
        }
    else:
        part0 = {
            'shaderIndex': node.part0.DW0 & 0xFFFFFF,
            'geomMask': (node.part0.DW0 >> 24) & 0xFF,
            'instanceContribution': node.part0.DW1 & 0xFFFFFF,
            'pad0': (node.part0.DW1 >> 24) & 0x1F,
            'DisableOpacityCull': (node.part0.DW1 >> 29) & 0x1,
            'OpaqueGeometry': (node.part0.DW1 >> 30) & 0x1,
            'pad1': (node.part0.DW1 >> 31) & 0x1,
            'startNodePtr': node.part0.QW_startNodePtr & 0xFFFFFFFFFFFF,
            'instFlags': (node.part0.QW_startNodePtr >> 48) & 0xFF,
        }

    return {
        'part0': {
            **part0,
            'world2obj_vx': [node.part0.world2obj_vx_x, node.part0.world2obj_vx_y, node.part0.world2obj_vx_z],
            'world2obj_vy': [node.part0.world2obj_vy_x, node.part0.world2obj_vy_y, node.part0.world2obj_vy_z],
            'world2obj_vz': [node.part0.world2obj_vz_x, node.part0.world2obj_vz_y, node.part0.world2obj_vz_z],
            'obj2world_p': [node.part0.obj2world_p_x, node.part0.obj2world_p_y, node.part0.obj2world_p_z]
        },
        'part1': {
            'bvh_ptr': node.part1.bvh_ptr,
            'instance_id': node.part1.instance_id,
            'instance_index': node.part1.instance_index,
            'obj2world_vx': [node.part1.obj2world_vx_x, node.part1.obj2world_vx_y, node.part1.obj2world_vx_z],
            'obj2world_vy': [node.part1.obj2world_vy_x, node.part1.obj2world_vy_y, node.part1.obj2world_vy_z],
            'obj2world_vz': [node.part1.obj2world_vz_x, node.part1.obj2world_vz_y, node.part1.obj2world_vz_z],
            'world2obj_p': [node.part1.world2obj_p_x, node.part1.world2obj_p_y, node.part1.world2obj_p_z]
        }
    }

class NodeType:
    NODE_TYPE_MIXED = 0x0
    NODE_TYPE_INTERNAL = 0x0
    NODE_TYPE_INSTANCE = 0x1
    NODE_TYPE_QUAD128_STOC = 0x2
    NODE_TYPE_PROCEDURAL = 0x3
    NODE_TYPE_QUAD = 0x4
    NODE_TYPE_QUAD128 = 0x5
    NODE_TYPE_MESHLET = 0x6
    NODE_TYPE_INVALID = 0x7

class VkAabb(ctypes.Structure):
    _fields_ = (
        ('min_x', ctypes.c_float),
        ('min_y', ctypes.c_float),
        ('min_z', ctypes.c_float),
        ('max_x', ctypes.c_float),
        ('max_y', ctypes.c_float),
        ('max_z', ctypes.c_float),
    )

class AnvAccelStructHeader(ctypes.Structure):
    _fields_ = (
        ('rootNodeOffset', ctypes.c_uint64),
        ('aabb', VkAabb),
        ('instance_flags', ctypes.c_uint32),
        ('copy_dispatch_size', ctypes.c_uint32 * 3),
        ('compacted_size', ctypes.c_uint64),
        ('serialization_size', ctypes.c_uint64),
        ('size', ctypes.c_uint64),
        ('instance_count', ctypes.c_uint64),
        ('self_ptr', ctypes.c_uint64),
        ('enable_64b_rt', ctypes.c_uint32),
        ('padding', ctypes.c_uint32 * 41),
    )

class ChildData(ctypes.Structure):
    _fields_ = (
        ('blockIncr_and_startPrim', ctypes.c_uint8),  # Assuming child_data has startPrim field
    )

class AnvInternalNode(ctypes.Structure):
    _fields_ = (
        ('lower', ctypes.c_float * 3),
        ('child_offset', ctypes.c_uint32),
        ('node_type', ctypes.c_uint8),
        ('reserved', ctypes.c_uint8),
        ('exp_x', ctypes.c_int8),
        ('exp_y', ctypes.c_int8),
        ('exp_z', ctypes.c_int8),
        ('node_mask', ctypes.c_uint8),
        ('child_data', ChildData * 6),
        ('lower_x', ctypes.c_uint8 * 6),
        ('upper_x', ctypes.c_uint8 * 6),
        ('lower_y', ctypes.c_uint8 * 6),
        ('upper_y', ctypes.c_uint8 * 6),
        ('lower_z', ctypes.c_uint8 * 6),
        ('upper_z', ctypes.c_uint8 * 6),
    )

class AnvPrimLeafDesc(ctypes.Structure):
    _fields_ = (
        ('shader_index_and_geom_mask', ctypes.c_uint32),
        ('geometry_id_and_flags', ctypes.c_uint32),
    )

class AnvQuadLeafNode(ctypes.Structure):
    _fields_ = (
        ('leaf_desc', AnvPrimLeafDesc),
        ('prim_index0', ctypes.c_uint32),
        ('prim_index1_and_flags', ctypes.c_uint32),
        ('v', (ctypes.c_float * 3) * 4),
    )

class AnvProceduralLeafNode(ctypes.Structure):
    _fields_ = (
        ('leaf_desc', AnvPrimLeafDesc),
        ('DW1', ctypes.c_uint32),
        ('primIndex', ctypes.c_uint32 * 13),
    )

class InstanceLeafPart0(ctypes.Structure):
    _fields_ = (
        ('DW0', ctypes.c_uint32),
        ('DW1', ctypes.c_uint32),
        ('QW_startNodePtr', ctypes.c_uint64),
        ('world2obj_vx_x', ctypes.c_float),
        ('world2obj_vx_y', ctypes.c_float),
        ('world2obj_vx_z', ctypes.c_float),
        ('world2obj_vy_x', ctypes.c_float),
        ('world2obj_vy_y', ctypes.c_float),
        ('world2obj_vy_z', ctypes.c_float),
        ('world2obj_vz_x', ctypes.c_float),
        ('world2obj_vz_y', ctypes.c_float),
        ('world2obj_vz_z', ctypes.c_float),
        ('obj2world_p_x', ctypes.c_float),
        ('obj2world_p_y', ctypes.c_float),
        ('obj2world_p_z', ctypes.c_float),
    )

class InstanceLeafPart1(ctypes.Structure):
    _fields_ = (
        ('bvh_ptr', ctypes.c_uint64),
        ('instance_id', ctypes.c_uint32),
        ('instance_index', ctypes.c_uint32),
        ('obj2world_vx_x', ctypes.c_float),
        ('obj2world_vx_y', ctypes.c_float),
        ('obj2world_vx_z', ctypes.c_float),
        ('obj2world_vy_x', ctypes.c_float),
        ('obj2world_vy_y', ctypes.c_float),
        ('obj2world_vy_z', ctypes.c_float),
        ('obj2world_vz_x', ctypes.c_float),
        ('obj2world_vz_y', ctypes.c_float),
        ('obj2world_vz_z', ctypes.c_float),
        ('world2obj_p_x', ctypes.c_float),
        ('world2obj_p_y', ctypes.c_float),
        ('world2obj_p_z', ctypes.c_float),
    )

class AnvInstanceLeaf(ctypes.Structure):
    _fields_ = (
        ('part0', InstanceLeafPart0),
        ('part1', InstanceLeafPart1),
    )

class BVHInterpreter:
    def __init__(self, data):
        self.enable_64b_rt = False;
        self.data = data
        self.nodes = []
        self.relationships = {}
        self.node_counter = 0

    def interpret_structure(self, offset, structure):
        size = ctypes.sizeof(structure)
        if(offset + size > len(self.data)):
            raise ValueError(
                f"Not enough data to interpret structure: {structure.__name__}, "
                f"required {size} bytes but only {len(self.data) - offset} bytes available."
            )
        buffer = self.data[offset:offset + size]
        return structure.from_buffer_copy(buffer)

    def parse_bvh(self):
        offset = 0
        # Interpret the header
        header = self.interpret_structure(offset, AnvAccelStructHeader)
        self.enable_64b_rt = header.enable_64b_rt
        offset += header.rootNodeOffset

        # Interpret the rootNode
        self.dfs_interpret_node(offset, AnvInternalNode)

        output = {
            'header': get_header_properties(header),
            'nodes': self.nodes,
            'relationships': self.relationships
        }
        return output

    def determine_child_structure(self, child_node_type):
        if child_node_type == NodeType.NODE_TYPE_MIXED:
            return AnvInternalNode
        elif child_node_type == NodeType.NODE_TYPE_INSTANCE:
            return AnvInstanceLeaf
        elif child_node_type == NodeType.NODE_TYPE_QUAD:
            return AnvQuadLeafNode
        elif child_node_type == NodeType.NODE_TYPE_PROCEDURAL:
            return AnvProceduralLeafNode
        else:
            raise ValueError(f"Unknown node type: {child_node_type}")

    def dfs_interpret_node(self, offset, structure):
        node = self.interpret_structure(offset, structure)
        node_id = self.node_counter;
        self.node_counter += 1

        if structure == AnvInternalNode:
            node_type_str = "AnvInternalNode"
            node_properties = get_internal_node_properties(node)
        elif structure == AnvInstanceLeaf:
            node_type_str = "AnvInstanceLeaf"
            node_properties = get_instance_leaf_properties(node, self.enable_64b_rt)
        elif structure == AnvQuadLeafNode:
            node_type_str = "AnvQuadLeafNode"
            node_properties = get_quad_leaf_properties(node)
        elif structure == AnvProceduralLeafNode:
            node_type_str = "AnvProceduralLeafNode"
            node_properties = get_aabb_leaf_properties(node)
        else:
            raise ValueError(f"Unknown structure type: {structure}")

        self.nodes.append({
            'id': node_id,
            'type': node_type_str,
            'properties': node_properties
        })

        self.relationships[node_id] = []

        if node_type_str == "AnvInternalNode":
            # DFS its children
            children_offset_start = offset + node.child_offset * 64 # this node's position + child_offset
            isFatLeaf = True if node.node_type != NodeType.NODE_TYPE_MIXED else False
            added_blocks = 0
            for i in range(6):
                blockIncr = node.child_data[i].blockIncr_and_startPrim & 0x3
                child_is_valid = not (node.lower_x[i] & 0x80) or (node.upper_x[i] & 0x80)
                if(not child_is_valid):
                    continue

                # now determine the children's type
                child_node_type = node.node_type if isFatLeaf else ((node.child_data[i].blockIncr_and_startPrim >> 2) & 0xf)

                # find where my child is
                child_offset = children_offset_start + 64 * added_blocks
                added_blocks += blockIncr

                child_node_id = self.dfs_interpret_node(child_offset, self.determine_child_structure(child_node_type))
                self.relationships[node_id].append(child_node_id)

        return node_id


def main():
    with open(sys.argv[1], 'rb') as file1:
        data = file1.read()
    interpreter = BVHInterpreter(data)
    json_output = interpreter.parse_bvh()
    with open("bvh_dump.json", 'w') as f:
        json.dump(json_output, f, indent=4)


if __name__=="__main__":
    main()
