from __future__ import annotations

import platform
from pathlib import Path
from typing import Dict, Optional, Tuple


def detect_platform_target() -> tuple[str, Optional[str], list[str]]:
    """
    Returns:
      os_name: darwin|windows|linux
      distro_id: ubuntu/debian/... when linux and detectable
      distro_like: ordered fallback ids from ID_LIKE
    """
    os_name = platform.system().lower()
    if os_name == "darwin":
        return ("darwin", None, [])
    if os_name.startswith("win"):
        return ("windows", None, [])

    distro_id = None
    distro_like: list[str] = []
    os_release = Path("/etc/os-release")
    if os_release.exists():
        vals: Dict[str, str] = {}
        for line in os_release.read_text(encoding="utf-8").splitlines():
            if "=" not in line or line.strip().startswith("#"):
                continue
            k, v = line.split("=", 1)
            vals[k.strip()] = v.strip().strip('"').strip("'")
        distro_id = vals.get("ID")
        like = vals.get("ID_LIKE", "")
        if like:
            distro_like = [x.strip() for x in like.split() if x.strip()]
    return ("linux", distro_id, distro_like)


def resolve_install_command(
    install_map: Dict[str, str],
) -> Tuple[Optional[str], Optional[str], list[str]]:
    """
    Resolve install command for current host.
    Returns (target_key, command, tried_keys).
    """
    os_name, distro_id, distro_like = detect_platform_target()
    tried: list[str] = []

    def get(key: Optional[str]) -> Optional[str]:
        if not key:
            return None
        tried.append(key)
        return install_map.get(key)

    if os_name in ("darwin", "windows"):
        cmd = get(os_name)
        return (os_name if cmd else None, cmd, tried)

    # linux distro-specific preference
    cmd = get(distro_id)
    if cmd:
        return (distro_id, cmd, tried)

    for key in distro_like:
        cmd = get(key)
        if cmd:
            return (key, cmd, tried)

    cmd = get("linux")
    if cmd:
        return ("linux", cmd, tried)
    return (None, None, tried)
