const std = @import("std");
const vk = @import("vk");

pub const ci: vk.DebugUtilsMessengerCreateInfoEXT = .{
    .message_severity = .{
        .error_bit_ext = true,
        .info_bit_ext = true,
        .verbose_bit_ext = true,
        .warning_bit_ext = true,
    },
    .message_type = .{
        .device_address_binding_bit_ext = true,
        .general_bit_ext = true,
        .performance_bit_ext = true,
        .validation_bit_ext = true,
    },
    .pfn_user_callback = &debug_callback,
    .p_user_data = null,
};

pub fn debug_callback(
    msg_severity: vk.DebugUtilsMessageSeverityFlagsEXT,
    msg_type: vk.DebugUtilsMessageTypeFlagsEXT,
    p_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT,
    _: ?*anyopaque,
) callconv(vk.vulkan_call_conv) vk.Bool32 {
    // ripped from std.log.defaultLog

    const data = p_data orelse return vk.FALSE;
    const message = data.p_message orelse return vk.FALSE;

    const severity_prefix = if (msg_severity.verbose_bit_ext)
        "verbose:"
    else if (msg_severity.info_bit_ext)
        "info:"
    else if (msg_severity.warning_bit_ext)
        "warning:"
    else if (msg_severity.error_bit_ext)
        "error:"
    else
        "?:";

    const type_prefix = if (msg_type.general_bit_ext)
        ""
    else if (msg_type.validation_bit_ext)
        "validation:"
    else if (msg_type.performance_bit_ext)
        "performance:"
    else if (msg_type.device_address_binding_bit_ext)
        "device_address_binding:"
    else
        "?:";

    const stderr = std.io.getStdErr().writer();
    var bw = std.io.bufferedWriter(stderr);
    const writer = bw.writer();

    std.debug.lockStdErr();
    defer std.debug.unlockStdErr();
    nosuspend {
        writer.print("vk-{s}{s} {s}\n", .{ severity_prefix, type_prefix, message }) catch return vk.FALSE;
        bw.flush() catch return vk.FALSE;
    }

    return vk.FALSE;
}
