"""Resolución de rutas: dónde está games.toml y dónde guardar los datos.

Compilado con Nuitka, ``__compiled__`` existe. En modo ``--onefile`` la carpeta del
binario real la expone ``NUITKA_ONEFILE_DIRECTORY`` (Nuitka 4.x); con versiones que usan
``NUITKA_ONEFILE_BINARY`` tomamos su carpeta; si no, ``sys.executable`` (standalone).
Ejecutando desde fuente usamos la raíz del proyecto (la carpeta que contiene ``jlauncher``).
"""

from __future__ import annotations

import os
import shutil
import sys
from pathlib import Path

CONFIG_NAME = "games.toml"

# Carpeta de soporte en macOS cuando corremos como .app: ~/Library/Application Support/…
APP_SUPPORT_VENDOR = "jailgames"
APP_SUPPORT_APP = "jlauncher"


def is_compiled() -> bool:
    """True si corremos como binario Nuitka (define ``__compiled__`` en cada módulo)."""
    return "__compiled__" in globals()


def base_dir() -> Path:
    """Carpeta base junto a la que viven games.toml y jlauncher_data."""
    if is_compiled():
        directory = os.environ.get("NUITKA_ONEFILE_DIRECTORY")
        if directory:
            return Path(directory).resolve()
        binary = os.environ.get("NUITKA_ONEFILE_BINARY")
        if binary:
            return Path(binary).resolve().parent
        return Path(sys.executable).resolve().parent
    # Desde fuente: raíz del proyecto = padre del paquete jlauncher/
    return Path(__file__).resolve().parent.parent


def macos_app_bundle() -> Path | None:
    """Ruta del .app si corremos como bundle de macOS (``…/jlauncher.app``); si no, None.

    En un app bundle el ejecutable vive en ``…/jlauncher.app/Contents/MacOS/jlauncher``,
    dentro de un árbol no escribible al instalarse en ``/Applications``. Detectarlo nos
    deja redirigir datos y settings a ``~/Library/Application Support``.
    """
    if not is_compiled() or sys.platform != "darwin":
        return None
    exe = Path(sys.executable).resolve()
    for parent in exe.parents:
        if parent.suffix == ".app":
            return parent
    return None


def app_icon_path() -> Path | None:
    """Ruta al PNG del icono para la UI (icono de ventana/Dock y diálogo «Quant a»).

    En .app vive en ``Contents/Resources/icon.png``; desde fuente, en ``assets/icon.png``.
    Devuelve None si no se encuentra.
    """
    bundle = macos_app_bundle()
    if bundle is not None:
        candidate = bundle / "Contents" / "Resources" / "icon.png"
    else:
        candidate = base_dir() / "icon" / "icon.png"
    return candidate if candidate.exists() else None


def support_dir() -> Path:
    """Carpeta de soporte escribible en macOS (.app); se crea si no existe."""
    root = (
        Path.home()
        / "Library"
        / "Application Support"
        / APP_SUPPORT_VENDOR
        / APP_SUPPORT_APP
    )
    root.mkdir(parents=True, exist_ok=True)
    return root


def writable_base() -> Path:
    """Base donde escribir datos/settings: Application Support si .app, si no base_dir()."""
    if macos_app_bundle() is not None:
        return support_dir()
    return base_dir()


def config_file() -> Path:
    """Ruta a games.toml.

    En .app vive en Application Support (editable y persistente); se siembra la primera vez
    desde ``Contents/Resources/games.toml`` del bundle. Si no, junto al ejecutable / raíz.
    """
    bundle = macos_app_bundle()
    if bundle is not None:
        target = writable_base() / CONFIG_NAME
        if not target.exists():
            seed = bundle / "Contents" / "Resources" / CONFIG_NAME
            if seed.exists():
                shutil.copy2(seed, target)
        return target
    return base_dir() / CONFIG_NAME


def data_root(data_dir: str = "jlauncher_data") -> Path:
    """Carpeta raíz de datos; se crea si no existe."""
    root = writable_base() / data_dir
    root.mkdir(parents=True, exist_ok=True)
    return root


def game_dir(root: Path, game_id: str) -> Path:
    """Carpeta de un juego: <root>/<id>/."""
    return root / game_id


def repo_dir(root: Path, game_id: str) -> Path:
    """Carpeta del clone git: <root>/<id>/repo/."""
    return game_dir(root, game_id) / "repo"


def metadata_dir(root: Path, game_id: str) -> Path:
    """Carpeta de metadata cacheada: <root>/<id>/metadata/."""
    return game_dir(root, game_id) / "metadata"
