from threading import Thread
from typing import Any, Callable, Self, Sequence

from .base import App
from .component import Component

class Bus(Component):
    def __init__(self, name: str = ..., owner: App = ..., *args, **kwargs): ...
    @classmethod
    def new(cls, *args, **kwargs) -> Self: ...
    def bind(self, name: str, method: Callable) -> None: ...
    def unbind(self, name: str, method: Callable | None = ...) -> None: ...
    def trigger(self, name: str, *args, **kwargs) -> None: ...

class MemoryBus(Bus):
    _events: dict[str, list[Callable]]
    def __init__(self, name: str = ..., owner: App = ..., *args, **kwargs): ...
    def bind(self, name: str, method: Callable) -> None: ...
    def unbind(self, name: str, method: Callable | None = ...) -> None: ...
    def trigger(self, name: str, *args, **kwargs) -> None: ...
    def _load(self, *args, **kwargs) -> None: ...
    def _unload(self, *args, **kwargs) -> None: ...
    def _get_state(self) -> dict[str, Sequence[Callable]]: ...
    def _set_state(self, state: dict[str, Sequence[Callable]]) -> None: ...

class RedisBus(Bus):
    SERIALIZER: Any
    GLOBAL_CHANNEL: str
    _delay: bool
    _events: dict[str, list[Callable]]
    _name: str
    _serializer: Any
    _global_channel: str
    _redis: Any
    _pubsub: Any
    _listener: RedisListener
    def __init__(self, name: str = ..., owner: App = ..., *args, **kwargs): ...
    def bind(self, name: str, method: Callable) -> None: ...
    def unbind(self, name: str, method: Callable | None = ...) -> None: ...
    def trigger(self, name: str, *args, **kwargs) -> None: ...
    def _load(self, *args, **kwargs) -> None: ...
    def _unload(self, *args, **kwargs) -> None: ...
    def _get_state(self) -> dict[str, Sequence[Callable]]: ...
    def _set_state(self, state: dict[str, Sequence[Callable]]) -> None: ...
    def _open(self) -> None: ...
    def _close(self) -> None: ...
    def _loop(self, safe: bool = ...) -> None: ...
    def _tick(self, item: dict[str, Any], safe: bool = ...) -> None: ...
    def _to_channel(self, name: str) -> str: ...

class RedisListener(Thread):
    _bus: RedisBus
    def __init__(self, bus: RedisBus): ...
    def run(self) -> None: ...
