"""Helpers around the app's plugin-icon install convention.

At load time the desktop app copies every PNG in a plugin's declared
``plugin_icons_dir`` into the app's flat icon set, prefixed with the plugin
id's first ``_``-segment — e.g. plugin id ``bambu_studio`` with an icon file
``cut.png`` installs as ``bambu_cut.png``. See ``_install_plugin_icons`` in
``PC Software/mixlar_mini.py`` (the source of truth this module mirrors). These
are pure, dependency-free helpers so a plugin (or its tests) can compute/
validate installed icon names off-app, without importing Qt or touching the
filesystem convention by hand.
"""
from __future__ import annotations

import os
from typing import List

#: Prefixes the app recognizes as a Font Awesome (qtawesome) icon name rather
#: than an installed PNG file. Mirrors the ``fa5s.``/``fa5r.``/``fa5b.``/``fa.``
#: styles qtawesome ships (solid, regular, brands, and the legacy ``fa.`` alias).
_FONTAWESOME_PREFIXES = ("fa5s.", "fa5r.", "fa5b.", "fa.")


def icon_prefix(plugin_id: str) -> str:
    """The short install prefix derived from a plugin id.

    ``"bambu_studio"`` -> ``"bambu"``; a plugin id with no ``_`` is its own
    prefix (``"govee"`` -> ``"govee"``).
    """
    return plugin_id.split("_")[0]


def installed_icon_name(plugin_id: str, filename: str) -> str:
    """The flat, installed name a bundled icon file gets copied to.

    ``installed_icon_name("bambu_studio", "cut.png")`` -> ``"bambu_cut.png"``.
    """
    return f"{icon_prefix(plugin_id)}_{filename}"


def is_fontawesome(name: str) -> bool:
    """True if ``name`` looks like a qtawesome icon spec rather than a filename.

    Matches the ``fa5s.``/``fa5r.``/``fa5b.``/``fa.`` prefixes used everywhere
    in the app (e.g. ``plugin_icon``, ``get_macro_action_icons`` values).
    """
    return name.startswith(_FONTAWESOME_PREFIXES)


def list_png_icons(icons_dir: str) -> List[str]:
    """List the ``*.png`` filenames directly inside ``icons_dir``.

    Returns ``[]`` if the directory doesn't exist — never raises. Case-
    insensitive extension match, mirroring the app's own scan.
    """
    if not icons_dir or not os.path.isdir(icons_dir):
        return []
    try:
        return sorted(
            f for f in os.listdir(icons_dir)
            if f.lower().endswith(".png")
        )
    except OSError:
        return []


__all__ = ["icon_prefix", "installed_icon_name", "is_fontawesome", "list_png_icons"]
