#!/usr/bin/env python3
"""Inventory iOS Asset Catalogs (imagesets + appiconsets) for parity tracking.

Scans both production asset catalogs:
  - iosApp/iosApp/Assets.xcassets/
  - iosApp/HoneyDue/Assets.xcassets/

Skips build/DerivedData output (PostHog examples etc.).

Output schema:
{
  "image_sets": [
    {"name": "outline", "path": "...", "files": ["outline.pdf"], "format": "pdf"},
    ...
  ],
  "app_icons": [
    {"name": "AppIcon", "path": "...", "sizes": ["1024x1024", ...]}
  ],
  "widget_assets": [
    { ...same shape as image_sets... }
  ]
}
"""
from __future__ import annotations

import json
from pathlib import Path
from typing import Any

REPO_ROOT = Path(__file__).resolve().parent.parent
MAIN_XCASSETS = REPO_ROOT / "iosApp" / "iosApp" / "Assets.xcassets"
WIDGET_XCASSETS = REPO_ROOT / "iosApp" / "HoneyDue" / "Assets.xcassets"
OUT_PATH = REPO_ROOT / "docs" / "ios-parity" / "assets.json"

_IMAGE_EXTS = {".pdf", ".png", ".jpg", ".jpeg", ".svg", ".heic"}


def infer_format(files: list[str]) -> str:
    exts = {Path(f).suffix.lower().lstrip(".") for f in files}
    image_exts = exts & {"pdf", "png", "jpg", "jpeg", "svg", "heic"}
    if not image_exts:
        return "unknown"
    if len(image_exts) == 1:
        return next(iter(image_exts))
    return "mixed(" + ",".join(sorted(image_exts)) + ")"


def list_asset_files(dir_path: Path) -> list[str]:
    out: list[str] = []
    for entry in sorted(dir_path.iterdir()):
        if entry.is_file() and entry.suffix.lower() in _IMAGE_EXTS:
            out.append(entry.name)
    return out


def describe_imageset(imageset_dir: Path) -> dict[str, Any]:
    name = imageset_dir.name[: -len(".imageset")]
    files = list_asset_files(imageset_dir)
    return {
        "name": name,
        "path": str(imageset_dir.relative_to(REPO_ROOT)),
        "files": files,
        "format": infer_format(files),
    }


def describe_appicon(appicon_dir: Path) -> dict[str, Any]:
    name = appicon_dir.name[: -len(".appiconset")]
    contents = appicon_dir / "Contents.json"
    sizes: list[str] = []
    files = list_asset_files(appicon_dir)
    if contents.is_file():
        try:
            data = json.loads(contents.read_text(encoding="utf-8"))
        except json.JSONDecodeError:
            data = {}
        for image in data.get("images", []):
            size = image.get("size")
            scale = image.get("scale")
            idiom = image.get("idiom")
            if size:
                label = size
                if scale:
                    label = f"{label}@{scale}"
                if idiom:
                    label = f"{label} ({idiom})"
                sizes.append(label)
    return {
        "name": name,
        "path": str(appicon_dir.relative_to(REPO_ROOT)),
        "sizes": sizes,
        "files": files,
    }


def walk_catalog(root: Path) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
    imagesets: list[dict[str, Any]] = []
    appicons: list[dict[str, Any]] = []
    if not root.is_dir():
        return imagesets, appicons
    for dirpath, dirnames, _ in root.walk() if hasattr(root, "walk") else _walk(root):
        p = Path(dirpath)
        if p.name.endswith(".imageset"):
            imagesets.append(describe_imageset(p))
            dirnames[:] = []  # don't recurse inside
        elif p.name.endswith(".appiconset"):
            appicons.append(describe_appicon(p))
            dirnames[:] = []
    imagesets.sort(key=lambda x: x["name"])
    appicons.sort(key=lambda x: x["name"])
    return imagesets, appicons


def _walk(root: Path):
    """Fallback walker for Python < 3.12 where Path.walk is unavailable."""
    import os

    for dirpath, dirnames, filenames in os.walk(root):
        yield dirpath, dirnames, filenames


def main() -> int:
    main_images, main_icons = walk_catalog(MAIN_XCASSETS)
    widget_images, widget_icons = walk_catalog(WIDGET_XCASSETS)

    output = {
        "image_sets": main_images,
        "app_icons": main_icons + widget_icons,
        "widget_assets": widget_images,
    }

    OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
    with OUT_PATH.open("w", encoding="utf-8") as f:
        json.dump(output, f, indent=2)
        f.write("\n")

    print(f"[extract_ios_assets] wrote {OUT_PATH}")
    print(
        f"  image_sets={len(output['image_sets'])}  "
        f"app_icons={len(output['app_icons'])}  "
        f"widget_assets={len(output['widget_assets'])}"
    )
    return 0


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