import threading
from collections.abc import Callable, Generator, Iterator
from threading import Thread
from typing import Any, Generic, TypeVar

from typing_extensions import override

__all__ = (
    "Local",
    "LocalManager",
    "LocalStack",
    "bgThread",
    "default_socket_timeout",
    "get_ident",
)

_T = TypeVar("_T")

def get_ident() -> int: ...
def default_socket_timeout(timeout: float | None) -> Generator[None, None, None]: ...

class bgThread(Thread):
    daemon: bool
    name: str
    def __init__(self, name: str | None = ..., **kwargs: Any) -> None: ...
    def body(self) -> None: ...
    def on_crash(self, msg: Any, *fmt: Any, **kwargs: Any) -> None: ...
    @override
    def run(self) -> None: ...
    def stop(self) -> None: ...

class Local:
    __storage__: dict[int, dict[str, Any]]
    __ident_func__: Callable[[], int]

    def __init__(self) -> None: ...
    def __iter__(self) -> Iterator[tuple[str, Any]]: ...
    def __call__(self, proxy: Any) -> Any: ...
    def __release_local__(self) -> None: ...
    def __getattr__(self, name: str) -> Any: ...
    @override
    def __setattr__(self, name: str, value: Any) -> None: ...
    @override
    def __delattr__(self, name: str) -> None: ...

class _LocalStack(Generic[_T]):
    @property
    def __ident_func__(self) -> Callable[[], int]: ...
    def __init__(self) -> None: ...
    def __release_local__(self) -> None: ...
    def __call__(self) -> Any: ...
    def push(self, obj: _T) -> list[_T]: ...
    def pop(self) -> _T: ...
    def __len__(self) -> int: ...
    @property
    def stack(self) -> list[_T]: ...
    @property
    def top(self) -> _T: ...

class LocalManager:
    locals: Any
    ident_func: Any
    def __init__(
        self, locals: Any | None = ..., ident_func: Any | None = ...
    ) -> None: ...
    def get_ident(self) -> int: ...
    def cleanup(self) -> None: ...

class _FastLocalStack(threading.local, Generic[_T]):
    stack: list[_T]
    def __init__(self) -> None: ...
    def __len__(self) -> int: ...
    @property
    def top(self) -> _T: ...

LocalStack: type[_FastLocalStack[Any] | _LocalStack[Any]]
