#!/usr/bin/env python
"""Find the error prefixes in various l10n used for precise prefix stripping."""

import re
import logging
from pathlib import Path
from argparse import ArgumentParser, Namespace
from collections import defaultdict

import polib

HERE = Path(__file__).parent

logger = logging.getLogger()
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")


def main() -> None:
    args = parse_cmdline()
    regexp = make_regexp(args.pgroot)
    update_file(args.dest, regexp)


def make_regexp(pgroot: Path) -> str:
    logger.info("looking for translations in %s", pgroot)
    msgids = "DEBUG INFO NOTICE WARNING ERROR LOG FATAL PANIC".split()
    bylang = defaultdict[str, list[str]](list)
    bylang["en"].extend(msgids)
    for fn in (pgroot / "src/backend/po").glob("*.po"):
        lang = fn.name.rsplit(".")[0]
        pofile = polib.pofile(str(fn))
        for msgid in msgids:
            if not (entry := pofile.find(msgid)):
                continue
            bylang[lang].append(entry.msgstr)

    pattern = "\n    | ".join(
        "%s  # %s" % (" | ".join(re.escape(msg) for msg in msgs), lang)
        for lang, msgs in sorted(bylang.items())
    )
    return rf'''    r"""
    ^ (?:
      {pattern}
    ) : \s+
    """,  # noqa: E501'''


def update_file(fn: Path, content: str) -> None:
    logger.info("updating %s", fn)

    with open(fn) as f:
        lines = f.read().splitlines()

    istart, iend = (
        i
        for i, line in enumerate(lines)
        if re.match(r"\s*(#|\.\.)\s*autogenerated:\s+(start|end)", line)
    )

    lines[istart + 1 : iend] = [content]

    with open(fn, "w") as f:
        for line in lines:
            f.write(line + "\n")


def parse_cmdline() -> Namespace:
    for default_pgroot in (
        HERE / "../../fs/postgres",  # it happens to be my laptop
        HERE / "../../postgres",  # the last entry is the default if none found
    ):
        if default_pgroot.exists():
            break

    default_pgroot = default_pgroot.resolve()
    default_dest = (HERE / "../psycopg/psycopg/pq/misc.py").resolve()

    parser = ArgumentParser(description=__doc__)
    parser.add_argument(
        "--pgroot",
        metavar="DIR",
        default=default_pgroot,
        type=Path,
        help="root PostgreSQL source directory [default: %(default)s]",
    )
    parser.add_argument(
        "--dest",
        default=default_dest,
        type=Path,
        help="the file to change [default: %(default)s]",
    )

    if not (opt := parser.parse_args()).pgroot.is_dir():
        parser.error("not a valid directory: {opt.pgroot}")

    return opt


if __name__ == "__main__":
    main()
