import inspect

from zayt.util.package_scan import scan_packages
from zayt.web.routing.decorator import (
    ATTRIBUTE_HANDLER,
    ATTRIBUTE_WEBSOCKET,
    HandlerInfo,
    WebSocketInfo,
)


def _is_handler(arg) -> bool:
    return inspect.iscoroutinefunction(arg) and (
        hasattr(arg, ATTRIBUTE_HANDLER) or hasattr(arg, ATTRIBUTE_WEBSOCKET)
    )


def discover_handlers(self, *modules):
    for item in scan_packages(*modules, predicate=_is_handler):
        handler, prefix = item if isinstance(item, tuple) else (item, None)

        handler_info: HandlerInfo = getattr(handler, ATTRIBUTE_HANDLER, None)
        websocket_info: WebSocketInfo = getattr(handler, ATTRIBUTE_WEBSOCKET, None)

        if handler_info:
            for method, path in handler_info.mappings:
                self.route(handler, method, path, prefix=prefix)

        if websocket_info:
            for path in websocket_info.paths:
                self.websocket(handler, path, prefix=prefix)
