"""macOS Keychain storage for worker machine credentials."""

from __future__ import annotations

import platform
import shutil
import subprocess
from urllib.parse import urlparse


def build_worker_token_ref(coordinator_url: str, worker_id: str) -> dict[str, str]:
    """Create a stable Keychain reference for a worker token."""
    parsed = urlparse(coordinator_url)
    host = parsed.netloc or parsed.path or coordinator_url
    return {
        "service": f"HiveCompute Worker ({host})",
        "account": worker_id,
    }


def store_worker_token(token: str, coordinator_url: str, worker_id: str) -> dict[str, str]:
    """Store a worker token in macOS Keychain and return the reference metadata."""
    _ensure_keychain_available()
    ref = build_worker_token_ref(coordinator_url, worker_id)
    subprocess.run(
        [
            "security",
            "add-generic-password",
            "-U",
            "-a",
            ref["account"],
            "-s",
            ref["service"],
            "-w",
            token,
        ],
        check=True,
        capture_output=True,
        text=True,
    )
    return ref


def load_worker_token(ref: dict[str, str]) -> str:
    """Read a worker token from macOS Keychain."""
    _ensure_keychain_available()
    result = subprocess.run(
        [
            "security",
            "find-generic-password",
            "-a",
            ref["account"],
            "-s",
            ref["service"],
            "-w",
        ],
        check=True,
        capture_output=True,
        text=True,
    )
    return result.stdout.strip()


def resolve_worker_token(config: dict) -> str:
    """Load the worker token from Keychain, falling back to legacy YAML storage."""
    ref = config.get("worker_token_keychain")
    if ref:
        if not isinstance(ref, dict) or "service" not in ref or "account" not in ref:
            raise RuntimeError(
                "worker_token_keychain must be a mapping with 'service' and 'account' keys. Re-run 'hive init'."
            )
        return load_worker_token(ref)
    if config.get("worker_token"):
        return config["worker_token"]
    raise RuntimeError("Worker token is not configured")


def describe_worker_token_storage(config: dict) -> str:
    """Return a short description of where the worker token is stored."""
    ref = config.get("worker_token_keychain")
    if ref:
        if not isinstance(ref, dict):
            return f"malformed keychain ref ({type(ref).__name__})"
        service = ref.get("service", "?")
        account = ref.get("account", "?")
        return f"macOS Keychain ({service} / {account})"
    if config.get("worker_token"):
        return "config file (legacy)"
    return "missing"


def _ensure_keychain_available() -> None:
    if platform.system() != "Darwin" or not shutil.which("security"):
        raise RuntimeError("macOS Keychain access requires the 'security' CLI on a Mac")
