"""Steam installation and game config path detection.

Finds the Steam root directory via Windows registry, common paths, and
environment variables. Locates game-specific cfg directories by checking
Steam library folders (including multiple library locations from
libraryfolders.vdf).
"""

import platform
import re
from pathlib import Path

from wled_controller.utils import get_logger

logger = get_logger(__name__)

# Game IDs and relative cfg paths within steamapps/common/
_GAME_PATHS: dict[str, dict[str, str]] = {
    "cs2": {
        "app_id": "730",
        "install_dir": "Counter-Strike Global Offensive",
        "cfg_subpath": "game/csgo/cfg",
    },
    "dota2": {
        "app_id": "570",
        "install_dir": "dota 2 beta",
        "cfg_subpath": "game/dota/cfg",
    },
}


def find_steam_root() -> Path | None:
    """Detect the Steam installation directory.

    Strategy:
      1. Windows: read HKCU\\Software\\Valve\\Steam\\SteamPath
      2. Fall back to common paths per platform
      3. Check STEAM_DIR environment variable

    Returns:
        Path to Steam root, or None if not found.
    """
    import os

    system = platform.system()

    # ── Windows registry ──
    if system == "Windows":
        try:
            import winreg

            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Valve\Steam")
            steam_path, _ = winreg.QueryValueEx(key, "SteamPath")
            winreg.CloseKey(key)
            p = Path(str(steam_path))
            if p.is_dir():
                logger.debug("Steam found via registry: %s", p)
                return p
        except (OSError, ImportError):
            pass

    # ── Common paths ──
    common_paths: list[Path] = []
    if system == "Windows":
        common_paths = [
            Path("C:/Program Files (x86)/Steam"),
            Path("C:/Program Files/Steam"),
        ]
    elif system == "Linux":
        home = Path.home()
        common_paths = [
            home / ".steam" / "root",
            home / ".steam" / "steam",
            home / ".local" / "share" / "Steam",
        ]
    elif system == "Darwin":
        common_paths = [
            Path.home() / "Library" / "Application Support" / "Steam",
        ]

    for candidate in common_paths:
        if candidate.is_dir():
            logger.debug("Steam found at common path: %s", candidate)
            return candidate

    # ── Environment variable fallback ──
    env_dir = os.environ.get("STEAM_DIR")
    if env_dir:
        p = Path(env_dir)
        if p.is_dir():
            logger.debug("Steam found via STEAM_DIR env: %s", p)
            return p

    logger.debug("Steam installation not found")
    return None


def _parse_library_folders(steam_root: Path) -> list[Path]:
    """Parse libraryfolders.vdf to find all Steam library locations.

    Returns a list of library root paths (each containing a steamapps/ dir).
    The steam_root itself is always included as the first entry.
    """
    libraries: list[Path] = [steam_root]
    vdf_path = steam_root / "steamapps" / "libraryfolders.vdf"

    if not vdf_path.is_file():
        # Older Steam versions use config/libraryfolders.vdf
        vdf_path = steam_root / "config" / "libraryfolders.vdf"
        if not vdf_path.is_file():
            return libraries

    try:
        content = vdf_path.read_text(encoding="utf-8", errors="replace")
        # Match "path" entries in the VDF file
        # Format: "path"		"C:\\SteamLibrary"
        for match in re.finditer(r'"path"\s+"([^"]+)"', content):
            lib_path = Path(match.group(1).replace("\\\\", "\\"))
            if lib_path.is_dir() and lib_path not in libraries:
                libraries.append(lib_path)
    except OSError as e:
        logger.warning("Failed to read libraryfolders.vdf: %s", e)

    return libraries


def find_game_cfg_path(game: str) -> Path | None:
    """Find the cfg directory for a supported game.

    Args:
        game: Game identifier ("cs2" or "dota2").

    Returns:
        Path to the game's cfg directory, or None if not found.
    """
    game_info = _GAME_PATHS.get(game)
    if not game_info:
        logger.warning("Unknown game identifier: %s", game)
        return None

    steam_root = find_steam_root()
    if not steam_root:
        return None

    libraries = _parse_library_folders(steam_root)

    for lib in libraries:
        cfg_path = (
            lib / "steamapps" / "common" / game_info["install_dir"] / game_info["cfg_subpath"]
        )
        if cfg_path.is_dir():
            logger.debug("Found %s cfg at: %s", game, cfg_path)
            return cfg_path

    logger.debug("Game cfg not found for %s in any library folder", game)
    return None
