import datetime
import pkgutil
import re
from typing import TYPE_CHECKING, List

from .utils import lines_to_text, load_data

if TYPE_CHECKING:
    from .layout import KeyboardLayout


SCAN_CODES = load_data("scan_codes")


def substitute_lines(text: str, variable: str, lines: List[str]) -> str:
    prefix = "KALAMINE::"
    exp = re.compile(".*" + prefix + variable + ".*")

    indent = ""
    for line in text.split("\n"):
        m = exp.match(line)
        if m:
            indent = m.group().split(prefix)[0]
            break

    return exp.sub(lines_to_text(lines, indent), text)


def substitute_token(text: str, token: str, value: str) -> str:
    exp = re.compile("\\$\\{" + token + "(=[^\\}]*){0,1}\\}")
    return exp.sub(value, text)


def load_tpl(layout: "KeyboardLayout", ext: str, tpl: str = "base") -> str:
    date = datetime.date.today().isoformat()
    if tpl == "base":
        if layout.has_altgr or ext.startswith(".RC"):
            tpl = "full"
            if layout.has_1dk and ext.startswith(".xkb"):
                tpl = "full_1dk"
    bin = pkgutil.get_data(__package__, f"templates/{tpl}{ext}")
    if bin is None:
        return ""
    out = bin.decode("utf-8")
    out = substitute_lines(out, "GEOMETRY_base", layout.base)
    out = substitute_lines(out, "GEOMETRY_full", layout.full)
    out = substitute_lines(out, "GEOMETRY_altgr", layout.altgr)
    out = substitute_token(out, "KALAMINE", f"Generated by kalamine on {date}")
    for key, value in layout.meta.items():
        out = substitute_token(out, key, value)
    return out
