"""K8sClientProtocol — structural type for all K8s operations.

Methods return dict[str, Any] (not K8s model objects) so the fake client
doesn't need to construct real K8s API objects. The real client normalizes
K8s API responses to plain dicts before returning.
"""

from __future__ import annotations

from collections.abc import Iterator
from typing import Any, Protocol


class K8sClientProtocol(Protocol):
    """Structural type for K8s operations.

    Both K8sClient (real) and FakeK8sClient implement this protocol.
    SDK services depend on this protocol, never on a concrete client.
    """

    # ── Namespaces ──────────────────────────────────────────────

    def get_namespace(self, name: str) -> dict[str, Any]: ...

    def namespace_exists(self, name: str) -> bool: ...

    def create_namespace(self, name: str) -> dict[str, Any]: ...

    # ── Deployments ─────────────────────────────────────────────

    def create_deployment(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_deployment(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_deployment(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_deployment(self, namespace: str, name: str) -> None: ...

    def list_deployments(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Pods ────────────────────────────────────────────────────

    def create_pod(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def list_pods(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    def delete_pod(self, namespace: str, name: str) -> None: ...

    def exec_in_pod(
        self,
        namespace: str,
        name: str,
        command: list[str],
        tty: bool = False,
        container: str | None = None,
        stdin_data: str | None = None,
    ) -> str: ...

    def stream_pod_logs(
        self,
        namespace: str,
        name: str,
        follow: bool = False,
        tail_lines: int | None = None,
        since_seconds: int | None = None,
        previous: bool = False,
    ) -> Iterator[str]: ...

    # ── ConfigMaps ──────────────────────────────────────────────

    def create_configmap(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_configmap(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_configmap(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_configmap(self, namespace: str, name: str) -> None: ...

    def list_configmaps(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Secrets ─────────────────────────────────────────────────

    def create_secret(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_secret(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_secret(self, namespace: str, name: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def delete_secret(self, namespace: str, name: str) -> None: ...

    def list_secrets(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Services ────────────────────────────────────────────────

    def create_service(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_service(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_service(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_service(self, namespace: str, name: str) -> None: ...

    def list_services(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Ingress ─────────────────────────────────────────────────

    def create_ingress(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_ingress(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_ingress(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_ingress(self, namespace: str, name: str) -> None: ...

    def list_ingresses(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    def list_ingress_classes(self) -> list[dict[str, Any]]: ...

    def create_ingress_class(self, body: dict[str, Any]) -> None: ...

    # ── StatefulSets (stateful addons) ──────────────────────────

    def create_statefulset(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_statefulset(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_statefulset(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_statefulset(self, namespace: str, name: str) -> None: ...

    def list_statefulsets(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── PVCs (stateful addon storage) ───────────────────────────

    def create_pvc(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_pvc(self, namespace: str, name: str) -> dict[str, Any]: ...

    def delete_pvc(self, namespace: str, name: str) -> None: ...

    def list_pvcs(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Jobs ────────────────────────────────────────────────────

    def create_job(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def wait_for_job(self, namespace: str, name: str, timeout: int = 300) -> dict[str, Any]: ...

    def delete_job(self, namespace: str, name: str) -> None: ...

    # ── HPA ─────────────────────────────────────────────────────

    def create_hpa(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_hpa(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_hpa(self, namespace: str, name: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def delete_hpa(self, namespace: str, name: str) -> None: ...

    # ── NetworkPolicies (app isolation — Section 8.2) ───────────

    def create_network_policy(self, namespace: str, body: dict[str, Any]) -> dict[str, Any]: ...

    def get_network_policy(self, namespace: str, name: str) -> dict[str, Any]: ...

    def update_network_policy(
        self, namespace: str, name: str, body: dict[str, Any]
    ) -> dict[str, Any]: ...

    def delete_network_policy(self, namespace: str, name: str) -> None: ...

    def list_network_policies(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── DaemonSets ────────────────────────────────────────────────

    def list_daemonsets(
        self, namespace: str, labels: dict[str, str] | None = None
    ) -> list[dict[str, Any]]: ...

    # ── Nodes ────────────────────────────────────────────────────

    def list_nodes(self) -> list[dict[str, Any]]: ...

    # ── Cluster info ───────────────────────────────────────────

    @property
    def cluster_endpoint(self) -> str: ...

    def server_version(self) -> str: ...

    # ── Auth ────────────────────────────────────────────────────

    def can_i(
        self,
        verb: str,
        resource: str,
        namespace: str = "",
        api_group: str = "",
        subresource: str = "",
    ) -> bool: ...

    # ── StorageClasses ───────────────────────────────────────────

    def list_storage_classes(self) -> list[dict[str, Any]]: ...
