from typing import overload, Any, Callable, TypeVar
from .ffi import (
    CData,
    CharCData,
    ClientCData,
    DispatcherFuncT,
    DisplayCData,
    EventLoopCData,
    InterfaceCData,
    ListCData,
    ListenerCData,
    NotifyFuncT,
    QueueCData,
    ResourceCData,
    ResourceDestroyFuncT,
)

WAYLAND_VERSION_MAJOR: int
WAYLAND_VERSION_MINOR: int
WAYLAND_VERSION_MICRO: int

dispatcher_func: DispatcherFuncT
resource_destroy_func: ResourceDestroyFuncT
notify_func: NotifyFuncT

def wl_list_remove(list: ListCData) -> None: ...

# Event loop functionality
def wl_event_loop_create() -> EventLoopCData: ...
def wl_event_loop_destroy(event_loop: EventLoopCData) -> None: ...

# Display functionality
def wl_display_create() -> DisplayCData: ...
def wl_display_destroy(display: DisplayCData) -> None: ...
def wl_display_destroy_clients(display: DisplayCData) -> None: ...
def wl_display_flush_clients(display: DisplayCData) -> None: ...
def wl_display_get_event_loop(display: DisplayCData) -> EventLoopCData: ...
def wl_display_add_socket(display: DisplayCData, name: bytes) -> int: ...
def wl_display_add_socket_auto(display: DisplayCData) -> CharCData: ...
def wl_display_terminate(display: DisplayCData) -> None: ...
def wl_display_run(display: DisplayCData) -> None: ...
def wl_display_get_serial(display: DisplayCData) -> int: ...
def wl_display_next_serial(display: DisplayCData) -> int: ...
def wl_display_init_shm(display: DisplayCData) -> int: ...
def wl_display_add_shm_format(display: DisplayCData, format: int) -> int: ...
def wl_event_queue_destroy(queue: QueueCData) -> None: ...
def wl_display_connect(name: bytes | CData) -> DisplayCData: ...
def wl_display_connect_to_fd(fd: int) -> DisplayCData: ...
def wl_display_disconnect(display: DisplayCData) -> None: ...
def wl_display_get_fd(display: DisplayCData) -> int: ...
def wl_display_dispatch(display: DisplayCData) -> int: ...
def wl_display_dispatch_pending(display: DisplayCData) -> int: ...
def wl_display_dispatch_queue(display: DisplayCData, queue: QueueCData) -> int: ...
def wl_display_dispatch_queue_pending(
    display: DisplayCData, queue: QueueCData
) -> int: ...
def wl_display_roundtrip(display: DisplayCData) -> int: ...
def wl_display_roundtrip_queue(display: DisplayCData, queue: QueueCData) -> int: ...
def wl_display_get_error(display: DisplayCData) -> int: ...
def wl_display_read_events(display: DisplayCData) -> int: ...
def wl_display_prepare_read(display: DisplayCData) -> int: ...
def wl_display_prepare_read_queue(display: DisplayCData, queue: QueueCData) -> int: ...
def wl_display_flush(display: DisplayCData) -> int: ...
def wl_display_create_queue(display: DisplayCData) -> QueueCData: ...

# Client functionality
def wl_client_create(display: DisplayCData, fd: int) -> ClientCData: ...
def wl_client_destroy(client: ClientCData) -> None: ...
def wl_client_flush(client: ClientCData) -> None: ...
def wl_client_add_destroy_listener(
    client: ClientCData, listener: ListenerCData
) -> None: ...
def wl_client_get_object(client: ClientCData, id: int) -> ResourceCData: ...
def wl_client_get_credentials(
    client: ClientCData, pid: CData, uid: CData, gid: CData
) -> None: ...
def os_create_anonymous_file(size: int) -> int: ...

# Proxy functionality
def wl_proxy_marshal_array(proxy, opcode, args_ptr) -> None: ...
def wl_proxy_marshal_array_constructor(
    proxy, opcode, args_ptr, interface_ptr
) -> Any: ...

# Resource functionality
def wl_resource_post_event_array(
    resource: ResourceCData, opcode: int, args: CData
) -> None: ...
def wl_resource_post_error(
    resource: ResourceCData, code: int, msg: bytes, *args: str
) -> None: ...
def wl_resource_create(
    client: ClientCData, interface: InterfaceCData, version: int, id: int
) -> ResourceCData: ...
def wl_resource_set_dispatcher(
    resource: ResourceCData,
    dispatcher: DispatcherFuncT,
    implementation: CData,
    data: CData,
    destroy: ResourceDestroyFuncT,
) -> None: ...
def wl_resource_destroy(resource: ResourceCData) -> None: ...
def wl_resource_get_id(resource: ResourceCData) -> int: ...
def wl_resource_get_user_data(resource: ResourceCData) -> CData: ...
def wl_resource_get_version(resource: ResourceCData) -> int: ...
def wl_resource_get_client(resource: ResourceCData) -> ClientCData: ...
def wl_resource_add_destroy_listener(
    resource: ResourceCData, listener: ListenerCData
) -> None: ...

WL_EVENT_READABLE: int
WL_EVENT_WRITABLE: int
WL_EVENT_HANGUP: int
WL_EVENT_ERROR: int
