"""
Generate every raster brand asset from the master SVG (app_icon.svg).

Run this whenever app_icon.svg changes:

    python resources/icons/generate_icons.py        # from DuplicateFinderPY/
    python generate_icons.py                         # from resources/icons/

Outputs (all next to this script, in resources/icons/):
    app_icon.png        256x256  - Qt window + application icon (main.py, main_window.py)
    tray_icon.png       256x256  - system tray icon (main_window.py)
    app_icon.ico        multi    - Windows .exe + installer icon (build.bat, Setup.exe)
    app_icon_1024.png   1024x1024 - source for the macOS .icns (build_mac.sh -> iconutil)
    favicon.ico         multi    - web favicon (copied into the web project's wwwroot)

Uses only PyQt5 (QtSvg) + Pillow, both already project dependencies. No SVG
rasteriser (cairosvg/Inkscape) required.
"""

import sys
from pathlib import Path

from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QImage, QPainter
from PyQt5.QtSvg import QSvgRenderer
from PyQt5.QtWidgets import QApplication
from PIL import Image

_HERE = Path(__file__).resolve().parent
_SVG = _HERE / "app_icon.svg"

# Sizes baked into the multi-resolution Windows .ico (and favicon).
_ICO_SIZES = [16, 24, 32, 48, 64, 128, 256]
_FAVICON_SIZES = [16, 32, 48]


def _render_png(size: int, out_path: Path) -> None:
    """Rasterise the master SVG to a square PNG of the given size (transparent bg)."""
    renderer = QSvgRenderer(str(_SVG))
    image = QImage(QSize(size, size), QImage.Format_ARGB32)
    image.fill(Qt.transparent)
    painter = QPainter(image)
    painter.setRenderHint(QPainter.Antialiasing, True)
    painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
    renderer.render(painter)
    painter.end()
    if not image.save(str(out_path), "PNG"):
        raise RuntimeError(f"Failed to write {out_path}")


def _write_ico(out_path: Path, sizes: list, tmp_dir: Path) -> None:
    """Render each requested size from the SVG and bundle them into one .ico."""
    frames = []
    for sz in sizes:
        png = tmp_dir / f"_ico_{sz}.png"
        _render_png(sz, png)
        frames.append(Image.open(png).convert("RGBA"))
    # Pillow builds a multi-resolution ICO from the largest frame + appended frames,
    # so each size is a crisp render straight from the SVG rather than a downscale.
    frames.sort(key=lambda im: im.size[0], reverse=True)
    frames[0].save(
        out_path, format="ICO",
        sizes=[(s, s) for s in sorted(sizes, reverse=True)],
        append_images=frames[1:],
    )


def main() -> int:
    if not _SVG.exists():
        print(f"ERROR: master SVG not found: {_SVG}", file=sys.stderr)
        return 1

    # A QApplication is needed for the raster paint engine used by QImage/QPainter.
    app = QApplication.instance() or QApplication(sys.argv)

    tmp_dir = _HERE / "_gen_tmp"
    tmp_dir.mkdir(exist_ok=True)
    try:
        _render_png(256, _HERE / "app_icon.png")
        _render_png(256, _HERE / "tray_icon.png")
        _render_png(1024, _HERE / "app_icon_1024.png")
        _write_ico(_HERE / "app_icon.ico", _ICO_SIZES, tmp_dir)
        _write_ico(_HERE / "favicon.ico", _FAVICON_SIZES, tmp_dir)
    finally:
        for f in tmp_dir.glob("*.png"):
            f.unlink(missing_ok=True)
        tmp_dir.rmdir()

    for name in ("app_icon.png", "tray_icon.png", "app_icon_1024.png",
                 "app_icon.ico", "favicon.ico"):
        p = _HERE / name
        print(f"  {name:18} {p.stat().st_size:>8,} bytes")
    print("Done. All brand assets regenerated from app_icon.svg.")
    del app
    return 0


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