
struct io_uring_sqe {
    opcode: u8
    flags: u8
    ioprio: u16
    fd: i32
    off: u64 // offset, aka. addr2
    addr: u64 // aka. splice_off_in
    len: u32 // buffer size or number of iovecs
    rw_flags: u32
    user_data: u64 // data to be passed back at completion time
    buf_index: u16 // aka. buf_group
    personality: u16
    file_index: u32 // aka. splice_fd_in: i32
    pad2: [u64 x 2]
    // pad: [u8 x 8]
}

struct io_uring_cqe {
    user_data: u64
    res: i32
    flags: u32
}

struct io_uring_sq {
        khead: *u32
        ktail: *u32
        kring_mask: *u32
        kring_entries: *u32
        kflags: *u32
        kdropped: *u32
        array: *u32
        sqes: *[<io_uring_sqe>]
        sqe_head: u32
        sqe_tail: u32
        ring_sz: uint
        ring_ptr: ptr
        pad: [u32 x 4]
}

struct io_uring_cq {
        khead: *u32
        ktail: *u32
        kring_mask: *u32
        kring_entries: *u32
        kflags: *u32
        koverflow: *u32
        cqes: *[<io_uring_cqe>]
        ring_sz: uint
        ring_ptr: ptr
        pad: [u32 x 4]
}

struct io_uring {
    sq: <io_uring_sq> (@undefined)
    cq: <io_uring_cq> (@undefined)
    flags: u32 (@undefined)
    ring_fd: i32 (@undefined)
    features: u32 (@undefined)
    pad: [u32 x 3] (@undefined)
}

// struct io_uring_params {
//     sq_entries: u32
//     cq_entries: u32
//     flags: u32
//     sq_thread_cpu: u32
//     sq_thread_idle: u32
//     features: u32
//     wq_fd: u32
//     resv: [u32 x 3]
//     sq_off: <io_sqring_offsets>
//     cq_off: <io_cqring_offsets>
// }

enum IOSQE {
    FIXED_FILE_BIT
    IO_DRAIN_BIT
    IO_LINK_BIT
    IO_HARDLINK_BIT
    ASYNC_BIT
    BUFFER_SELECT_BIT
}

enum IORING_OP {
    NOP
    READV
    WRITEV
    FSYNC
    READ_FIXED
    WRITE_FIXED
    POLL_ADD
    POLL_REMOVE
    SYNC_FILE_RANGE
    SENDMSG
    RECVMSG
    TIMEOUT
    TIMEOUT_REMOVE
    ACCEPT
    ASYNC_CANCEL
    LINK_TIMEOUT
    CONNECT
    FALLOCATE
    OPENAT
    CLOSE
    FILES_UPDATE
    STATX
    READ
    WRITE
    FADVISE
    MADVISE
    SEND
    RECV
    OPENAT2
    EPOLL_CTL
    SPLICE
    PROVIDE_BUFFERS
    REMOVE_BUFFERS
    TEE
    SHUTDOWN
    RENAMEAT
    UNLINKAT
    MKDIRAT
    SYMLINKAT
    LINKAT
    MSG_RING
    FSETXATTR
    SETXATTR
    FGETXATTR
    GETXATTR
    SOCKET
    URING_CMD
    SEND_ZC
    SENDMSG_ZC
    READ_MULTISHOT
    WAITID
    FUTEX_WAIT
    FUTEX_WAKE
    FUTEX_WAITV
    FIXED_FD_INSTALL
    FTRUNCATE
    BIND
    LISTEN
    RECV_ZC
    EPOLL_WAIT
    READV_FIXED
    WRITEV_FIXED
    PIPE
    NOP128
    URING_CMD128
    LAST
}

enum IORING_SQE_FLAGS {
        FIXED_FILE_BIT
        IO_DRAIN_BIT
        IO_LINK_BIT
        IO_HARDLINK_BIT
        ASYNC_BIT
        BUFFER_SELECT_BIT
        CQE_SKIP_SUCCESS_BIT
}

// Init
fn io_uring_queue_init(entries: u32, ring: io_uring, flags: u32) i32;
// Register file descriptors
fn io_uring_register_files(ring: io_uring, files: *[i32], nr_files: u32) i32;
// Submit
fn io_uring_submit_and_wait(ring: io_uring, wait_nr: u32) i32;
fn io_uring_submit(ring: io_uring) i32;
// Submission queue events (sqe)
fn io_uring_get_sqe(ring: io_uring) ?io_uring_sqe;
fn io_uring_sqe_set_flags(ring: io_uring, flags: u32);
// Completion queue events (cqe)
fn __io_uring_get_cqe(ring: io_uring, cqe_ptr: *?io_uring_cqe, submit: u32, wait_nr: u32, sigmask: ?ptr) i32;
