from pathlib import Path

from pyrandyos.utils.stack import top_package_dir_path
from pyrandyos.gui.icons.iconfont.sources import THIRDPARTY_FONTSPEC
from pyrandyos.gui.icons.utils import legalize_iconname
from pyrandyos.gui.icons.iconfont.fontspec import (
    ICON_ASSETS_DIR, THIRDPARTY_DIR, IconFontSpec
)

SCRIPTPATH = Path(__file__)
HERE = SCRIPTPATH.parent
NAMES_PY = 'names.py'
PYRANDYOS_DIR = top_package_dir_path('pyrandyos')
PYRANDYOS_ROOT = PYRANDYOS_DIR.parent
SCRIPT_RELPATH = SCRIPTPATH.relative_to(PYRANDYOS_ROOT)
AUTOHEADER = f'''
# This file is auto-generated by {SCRIPT_RELPATH.as_posix()}  # noqa: E501
# Do not edit.
'''.lstrip()
INIT_TEMPLATE_FILE = HERE/'init_template.py'
INIT_TEMPLATE = INIT_TEMPLATE_FILE.read_text()


def update_from_spec():
    ICON_ASSETS_DIR.mkdir(exist_ok=True)

    for fontmod, fontspec in THIRDPARTY_FONTSPEC.items():
        fontspec.initialize(fontmod, ICON_ASSETS_DIR)
        relmodname = fontspec.relative_module_qualname
        modparts = relmodname.split('.')

        levels = 1
        p = THIRDPARTY_DIR
        for part in modparts:
            levels += 1
            p /= part
            p.mkdir(exist_ok=True)
            init = p/'__init__.py'
            init.touch()

        generate_init(p, levels, fontspec)
        generate_names(p, fontspec)


def generate_init(p: Path, levels: int, fontspec: IconFontSpec):
    init = p/'__init__.py'
    s = f'{AUTOHEADER}{INIT_TEMPLATE}'
    s = s.replace('FONTCLASSNAME', fontspec.classname)
    s = s.replace("'FONTSPECNAME'",
                  repr(fontspec.target_relative_class_qualname))
    s = s.replace('\nfrom .', f"\nfrom {'.'*levels}.")
    init.write_text(s)


def generate_names(p: Path, fontspec: IconFontSpec):
    outf = p/NAMES_PY
    s = str(AUTOHEADER)
    for k, v in fontspec.charmap.items():
        newname = legalize_iconname(k)
        line = f"{newname} = {v}"
        if len(line) > 79:
            line += "  # noqa: E501"

        s += f"{line}\n"

    outf.write_text(s)


if __name__ == "__main__":
    update_from_spec()
