#!/usr/bin/env python3
"""Regenerate app/utils/languages.py from ISO 639-1 and CLDR.

Every ISO 639-1 alpha-2 code becomes an entry. The display name is the CLDR
endonym where CLDR knows the language, and the English ISO name for the
remainder. Writing direction comes from CLDR's character order.

Needs the dev extra: pip install -e ".[dev]"
"""

import subprocess
import sys
from pathlib import Path

import pycountry
from babel import Locale
from babel.localedata import locale_identifiers

TARGET = Path(__file__).resolve().parents[1] / "app" / "utils" / "languages.py"

HEADER = '''"""ISO 639-1 languages, their display names and writing direction.

Generated by utils/generate_languages.py — edit that script, not this file.

Display names are CLDR endonyms where CLDR covers the language and the English
ISO 639-1 name for the {fallback} codes it does not.
"""

LANGUAGES = {{
'''

FOOTER = """}}

RTL_LANGUAGES = frozenset({rtl})
"""


def collect():
    """Return (code -> display name) and the set of right-to-left codes."""
    cldr = {code for code in locale_identifiers() if len(code) == 2 and code.isalpha()}
    names, rtl, fallbacks = {}, set(), 0

    for language in sorted(
        pycountry.languages, key=lambda item: getattr(item, "alpha_2", "")
    ):
        code = getattr(language, "alpha_2", None)
        if not code:
            continue
        if code in cldr:
            locale = Locale.parse(code)
            names[code] = locale.get_display_name(code)
            if locale.character_order == "right-to-left":
                rtl.add(code)
        else:
            names[code] = language.name
            fallbacks += 1

    return names, rtl, fallbacks


def render(names, rtl, fallbacks):
    """Return the module source, English first and the rest by code."""
    ordered = ["en"] + [code for code in sorted(names) if code != "en"]
    body = "".join(f'    "{code}": "{names[code]}",\n' for code in ordered)
    listed = ", ".join(f'"{code}"' for code in sorted(rtl))
    return (
        HEADER.format(fallback=fallbacks) + body + FOOTER.format(rtl="{" + listed + "}")
    )


def main():
    names, rtl, fallbacks = collect()
    TARGET.write_text(render(names, rtl, fallbacks), encoding="utf-8")
    subprocess.run([sys.executable, "-m", "ruff", "format", str(TARGET)], check=False)
    print(
        f"{len(names)} languages, {len(rtl)} right-to-left, "
        f"{fallbacks} without a CLDR endonym"
    )
    return 0


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