from typing import Any, Generic, TypeVar, overload

__all__ = ['HassDict', 'HassEntryKey', 'HassKey']

_T = TypeVar('_T')

class _Key(Generic[_T]):
    def __init__(self, value: str, /) -> None: ...
    def __len__(self) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __getitem__(self, index: int) -> str: ...

class HassEntryKey(_Key[_T]): ...
class HassKey(_Key[_T]): ...

class HassDict(dict[_Key[Any] | str, Any]):
    @overload
    def __getitem__(self, key: HassEntryKey[_S]) -> dict[str, _S]: ...
    @overload
    def __getitem__(self, key: HassKey[_S]) -> _S: ...
    @overload
    def __getitem__(self, key: str) -> Any: ...
    @overload
    def __setitem__(self, key: HassEntryKey[_S], value: dict[str, _S]) -> None: ...
    @overload
    def __setitem__(self, key: HassKey[_S], value: _S) -> None: ...
    @overload
    def __setitem__(self, key: str, value: Any) -> None: ...
    @overload
    def setdefault(self, key: HassEntryKey[_S], default: dict[str, _S], /) -> dict[str, _S]: ...
    @overload
    def setdefault(self, key: HassKey[_S], default: _S, /) -> _S: ...
    @overload
    def setdefault(self, key: str, default: None = None, /) -> Any | None: ...
    @overload
    def setdefault(self, key: str, default: Any, /) -> Any: ...
    @overload
    def get(self, key: HassEntryKey[_S], /) -> dict[str, _S] | None: ...
    @overload
    def get(self, key: HassEntryKey[_S], default: _U, /) -> dict[str, _S] | _U: ...
    @overload
    def get(self, key: HassKey[_S], /) -> _S | None: ...
    @overload
    def get(self, key: HassKey[_S], default: _U, /) -> _S | _U: ...
    @overload
    def get(self, key: str, /) -> Any | None: ...
    @overload
    def get(self, key: str, default: Any, /) -> Any: ...
    @overload
    def pop(self, key: HassEntryKey[_S], /) -> dict[str, _S]: ...
    @overload
    def pop(self, key: HassEntryKey[_S], default: dict[str, _S], /) -> dict[str, _S]: ...
    @overload
    def pop(self, key: HassEntryKey[_S], default: _U, /) -> dict[str, _S] | _U: ...
    @overload
    def pop(self, key: HassKey[_S], /) -> _S: ...
    @overload
    def pop(self, key: HassKey[_S], default: _S, /) -> _S: ...
    @overload
    def pop(self, key: HassKey[_S], default: _U, /) -> _S | _U: ...
    @overload
    def pop(self, key: str, /) -> Any: ...
    @overload
    def pop(self, key: str, default: _U, /) -> Any | _U: ...
