from __future__ import annotations

import json
import os
import platform
import subprocess
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
ASSETS = ROOT / "assets"
DATA = ROOT / "data"


def _run_py(script: str) -> dict:
    path = ROOT / "tools" / script
    if not path.exists():
        return {"ok": False, "error": f"missing {script}"}
    try:
        p = subprocess.run([sys.executable, str(path)], cwd=ROOT, capture_output=True, text=True, timeout=20)
        return {
            "ok": p.returncode == 0,
            "returncode": p.returncode,
            "stdout": p.stdout[-4000:],
            "stderr": p.stderr[-2000:],
        }
    except subprocess.TimeoutExpired as exc:
        return {
            "ok": False,
            "timeout": True,
            "stdout": (exc.stdout or "")[-2000:] if isinstance(exc.stdout, str) else "",
            "stderr": (exc.stderr or "")[-1000:] if isinstance(exc.stderr, str) else "",
        }


def check_pystray() -> dict:
    result = {"pystray_import": False, "win32_backend_import": None, "backend": "", "error": ""}
    try:
        import pystray
        result["pystray_import"] = True
        result["backend"] = str(getattr(pystray, "_backend", "") or getattr(pystray, "backend", "") or "")
        if sys.platform.startswith("win"):
            try:
                import pystray._win32  # type: ignore
                result["win32_backend_import"] = True
                if not result["backend"]:
                    result["backend"] = "pystray._win32"
            except Exception as exc:
                result["win32_backend_import"] = False
                result["error"] = str(exc)
    except Exception as exc:
        result["error"] = str(exc)
    result["ok"] = bool(result["pystray_import"]) and (not sys.platform.startswith("win") or result["win32_backend_import"] is not False)
    return result


def icon_files() -> dict:
    expected = [16, 20, 24, 30, 32, 40, 48, 60, 64, 72, 80, 96, 128, 256]
    pngs = []
    missing = []
    for size in expected:
        p = ASSETS / f"nexaoffice_icon_{size}.png"
        if p.exists():
            pngs.append(size)
        else:
            missing.append(size)
    return {
        "assets_dir": str(ASSETS),
        "ico_exists": (ASSETS / "nexaoffice.ico").exists(),
        "png_sizes": pngs,
        "missing_png_sizes": missing,
        "generator_exists": (ROOT / "tools" / "generate_app_icons.py").exists(),
        "verifier_exists": (ROOT / "tools" / "verify_icon_assets.py").exists(),
        "cache_tool_exists": (ROOT / "tools" / "refresh_windows_icon_cache.bat").exists(),
    }


def main() -> int:
    payload = {
        "ok": True,
        "python": sys.version.split()[0],
        "platform": platform.platform(),
        "executable": sys.executable,
        "cwd": str(ROOT),
        "appdata": os.environ.get("APPDATA", ""),
        "localappdata": os.environ.get("LOCALAPPDATA", ""),
        "pystray": check_pystray(),
        "icons": icon_files(),
        "verify_icon_assets": _run_py("verify_icon_assets.py"),
        "generate_app_icons_available": (ROOT / "tools" / "generate_app_icons.py").exists(),
        "build_script": (ROOT / "build_exe.bat").exists(),
        "run_script": (ROOT / "run_from_source.bat").exists(),
    }
    payload["ok"] = bool(payload["pystray"].get("ok")) and bool(payload["verify_icon_assets"].get("ok"))
    print(json.dumps(payload, ensure_ascii=False, indent=2))
    return 0 if payload["ok"] else 1


if __name__ == "__main__":
    raise SystemExit(main())
