from collections.abc import Iterable
from typing import Any, Literal, NoReturn, Protocol, overload, type_check_only

from docker import APIClient
from docker.models.configs import ConfigCollection
from docker.models.containers import ContainerCollection
from docker.models.images import ImageCollection
from docker.models.networks import NetworkCollection
from docker.models.nodes import NodeCollection
from docker.models.plugins import PluginCollection
from docker.models.secrets import SecretCollection
from docker.models.services import ServiceCollection
from docker.models.swarm import Swarm
from docker.models.volumes import VolumeCollection
from docker.types import CancellableStream

@type_check_only
class _Environ(Protocol):
    def __getitem__(self, k: str, /) -> str: ...
    def keys(self) -> Iterable[str]: ...

class DockerClient:
    api: APIClient
    def __init__(self, *args, **kwargs) -> None: ...
    @classmethod
    def from_env(
        cls,
        *,
        version: str | None = None,
        timeout: int = ...,
        max_pool_size: int = ...,
        environment: _Environ | None = None,
        use_ssh_client: bool = False,
    ) -> DockerClient: ...
    @property
    def configs(self) -> ConfigCollection: ...
    @property
    def containers(self) -> ContainerCollection: ...
    @property
    def images(self) -> ImageCollection: ...
    @property
    def networks(self) -> NetworkCollection: ...
    @property
    def nodes(self) -> NodeCollection: ...
    @property
    def plugins(self) -> PluginCollection: ...
    @property
    def secrets(self) -> SecretCollection: ...
    @property
    def services(self) -> ServiceCollection: ...
    @property
    def swarm(self) -> Swarm: ...
    @property
    def volumes(self) -> VolumeCollection: ...

    @overload
    def events(self, *args, decode: Literal[False] | None = None, **kwargs) -> CancellableStream[str]: ...
    @overload
    def events(self, *args, decode: Literal[True] = ..., **kwargs) -> CancellableStream[dict[str, Any]]: ...

    def df(self) -> dict[str, Any]: ...
    def info(self, *args, **kwargs) -> dict[str, Any]: ...
    def login(self, *args, **kwargs) -> dict[str, Any]: ...
    def ping(self, *args, **kwargs) -> bool: ...
    def version(self, *args, **kwargs) -> dict[str, Any]: ...
    def close(self) -> None: ...
    def __getattr__(self, name: str) -> NoReturn: ...

from_env = DockerClient.from_env
