import asyncio
from typing import Optional, Protocol, Any, List, Dict, runtime_checkable

from event_systems.base.handler import Handler

# TODO: Write Documentation
# TODO: Unsubscribe

@runtime_checkable
class InstancedAsync(Protocol):
    async def start(self) -> None: ...

    async def stop(self) -> None: ...

    async def subscribe(self, event_name: str, fn: Handler) -> Dict[str, Any]: ...

    async def post(self, event_name: str, event_data: Dict[str, Any]) -> None: ...

    async def get_subscriptions(self) -> Dict[str, List[Handler]]: ...

    async def process_all_events(self) -> None: ...

    async def is_running(self) -> bool: ...

    def get_loop(self) -> asyncio.AbstractEventLoop: ...


class SingletonAsync(Protocol):
    @classmethod
    async def start(cls) -> None: ...

    @classmethod
    async def stop(cls) -> None: ...

    @classmethod
    async def subscribe(cls, event_name: str, fn: Handler) -> Dict[str, Any]: ...

    @classmethod
    async def post(cls, event_name: str, event_data: Dict[str, Any]) -> None: ...

    @classmethod
    async def get_subscriptions(cls) -> Dict[str, List[Handler]]: ...

    @classmethod
    async def process_all_events(cls) -> None: ...

    @classmethod
    async def is_running(cls) -> bool: ...

    @classmethod
    async def get_instance(cls) -> Optional[object]: ...
