import bpy


def tryGetImage(node: bpy.types.Node, name:str) -> bpy.types.Image or None:
    # check if the node is a texture node
    if node.type == "TEX_IMAGE":
        image = node.image
        if image: 
            if image.name == name:
                return node.image
            # Seems like the image name is stripping the .002 extension if our texture has that
            if image.name.startswith(name):
                # ends with numbers?
                namePostfix = image.name[len(name):]
                if len(namePostfix) > 1 and namePostfix.startswith(".") and namePostfix[1:].isnumeric():
                    return node.image
                elif namePostfix == ".png" or namePostfix == ".jpg" or namePostfix == ".jpeg" or namePostfix == ".webp":
                    return node.image
    
    # iterate graph inputs:
    elif "inputs" in node or getattr(node, "inputs", None) is not None:
        for input in node.inputs:
            image = tryGetImage(input, name)
            if image is not None:
                return image
            if input.is_linked:
                linked_node = input.links[0].from_node
                image = tryGetImage(linked_node, name)
                if image is not None:
                    return image
    return None
    
# iterates the shader sockets to find the image that matches the name
def tryFindImage(blender_shader_sockets, name: str) -> bpy.types.Image or None:
    count = len(blender_shader_sockets)
    if count == 0:
        return None
    for i in range(count):
        socket = blender_shader_sockets[i]
        # This seems to be a change in Blender 4.1
        if hasattr(socket, "socket"):
            socket = socket.socket
        if socket is None: 
            continue
        if socket.is_linked:
            node = socket.node
            image = tryGetImage(node, name)
            if image is not None:
                return (image, socketIdentifierToGltfName(socket.identifier))
            


def socketIdentifierToGltfName(identifier:str) -> str:
    if identifier == "Base Color":
        return "baseColorTexture"
    if identifier == "Normal":
        return "normalTexture"
    if identifier == "Metallic":
        return "metallicRoughnessTexture"
    if identifier == "Roughness":
        return "metallicRoughnessTexture"
    if identifier == "Occlusion":
        return "occlusionTexture"
    if identifier == "Emission":
        return "emissiveTexture"
    return ""