"""tbot health monitoring and lifecycle management.

tbot runs as an ECS sidecar container and generates short-lived credentials
via the Teleport Machine ID protocol (IAM join method).

Outputs:
  - identity at {data_dir}/identity/ (for tsh commands)
  - kubernetes at {data_dir}/kube/{cluster}/ (per-cluster kubeconfig)
"""

from __future__ import annotations

import asyncio
import logging
import os
from pathlib import Path

logger = logging.getLogger(__name__)

TBOT_DATA_DIR = Path(os.environ.get("TBOT_DATA_DIR", "/tbot-data"))
TELEPORT_PROXY = os.environ.get("TELEPORT_PROXY", "edgescaleai.teleport.sh:443")


class TbotManager:
    """Monitor tbot sidecar health and credential availability."""

    def __init__(self, data_dir: Path = TBOT_DATA_DIR) -> None:
        self.data_dir = data_dir
        self.identity_dir = data_dir / "identity"
        self.identity_path = self.identity_dir / "identity"
        self.kube_dir = data_dir / "kube"
        self.proxy = TELEPORT_PROXY

    @property
    def is_ready(self) -> bool:
        """Check if tbot has generated a valid identity file."""
        return self.identity_path.exists() and self.identity_path.stat().st_size > 0

    async def wait_ready(self, timeout: float = 60) -> bool:
        """Wait for tbot to generate credentials. Returns True if ready."""
        elapsed = 0.0
        interval = 2.0
        while elapsed < timeout:
            if self.is_ready:
                logger.info("tbot identity ready at %s", self.identity_path)
                return True
            await asyncio.sleep(interval)
            elapsed += interval
        logger.warning("tbot credentials not ready after %.0fs", timeout)
        return False

    def tsh_base_args(self) -> list[str]:
        """Return base tsh args for identity-based auth."""
        return [
            "tsh",
            "--proxy", self.proxy,
            "-i", str(self.identity_path),
            "--insecure",
        ]

    def tsh_env(self) -> dict[str, str]:
        """Return minimal environment for running tsh."""
        return {
            "PATH": "/usr/local/bin:/usr/bin:/bin",
            "HOME": "/tmp",
        }

    def get_kubeconfig(self, cluster: str) -> str | None:
        """Return path to tbot-generated kubeconfig for a cluster, or None."""
        kc = self.kube_dir / cluster / "kubeconfig.yaml"
        if kc.exists() and kc.stat().st_size > 0:
            return str(kc)
        # Also check for 'kubeconfig' without extension
        kc2 = self.kube_dir / cluster / "kubeconfig"
        if kc2.exists() and kc2.stat().st_size > 0:
            return str(kc2)
        return None

    def list_kube_clusters(self) -> list[str]:
        """List clusters that have kubeconfigs available."""
        if not self.kube_dir.exists():
            return []
        clusters = []
        for d in sorted(self.kube_dir.iterdir()):
            if d.is_dir():
                kc = d / "kubeconfig.yaml"
                kc2 = d / "kubeconfig"
                if (kc.exists() and kc.stat().st_size > 0) or (kc2.exists() and kc2.stat().st_size > 0):
                    clusters.append(d.name)
        return clusters

    def get_app_cert_dir(self, app_name: str) -> Path | None:
        """Return path to tbot-generated app cert directory, or None."""
        cert_dir = self.data_dir / f"app-{app_name}"
        if cert_dir.exists():
            return cert_dir
        return None

    def status(self) -> dict:
        """Return tbot status info for health checks."""
        return {
            "data_dir": str(self.data_dir),
            "ready": self.is_ready,
            "identity": self.is_ready,
            "kube_clusters": self.list_kube_clusters(),
        }


# Module-level singleton
tbot = TbotManager()
