#!/usr/bin/env python
"""Filter .po files to keep only entries for a specific module."""

from __future__ import annotations

import argparse
from pathlib import Path
from typing import Iterable

import polib


def _extract_modules_from_comment(entry: polib.POEntry) -> set[str]:
    """Return module names declared in translator comments (#.)."""

    tcomment = entry.tcomment or ""
    modules: set[str] = set()
    for line in tcomment.splitlines():
        stripped = line.strip()
        lowered = stripped.lower()
        if lowered.startswith("module:") or lowered.startswith("modules:"):
            _, _, tail = stripped.partition(":")
            for module in tail.split(","):
                module_name = module.strip()
                if module_name:
                    modules.add(module_name)
    return modules


def belongs_to_module(entry: polib.POEntry, module_name: str) -> bool:
    """Return True if the entry references ONLY the target module."""

    declared_modules = _extract_modules_from_comment(entry)
    if declared_modules:
        return declared_modules == {module_name}

    locations = [occ[0] for occ in entry.occurrences if occ and occ[0]]
    if locations:
        return all(module_name in location for location in locations)
    return False


def filter_po_file(path: Path, module_name: str, dry_run: bool = False) -> None:
    po = polib.pofile(str(path))
    kept_entries: list[polib.POEntry] = []
    removed = 0

    for entry in po:
        if entry.msgid == "":
            kept_entries.append(entry)
            continue

        if belongs_to_module(entry, module_name):
            kept_entries.append(entry)
        else:
            removed += 1

    if dry_run:
        print(
            f"[DRY-RUN] {path}: would keep {len(kept_entries)} entries, remove {removed} entries"
        )
        return

    new_po = polib.POFile()
    new_po.metadata = po.metadata

    for entry in kept_entries:
        new_po.append(entry)

    new_po.save(str(path))
    print(
        f"Filtered {path}: kept {len(kept_entries)} entries, removed {removed} entries"
    )


def parse_args(args: Iterable[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("module", help="Module technical name to keep")
    parser.add_argument("files", nargs="+", type=Path, help=".po files to filter")
    parser.add_argument("--dry-run", action="store_true", help="Only report counts")
    return parser.parse_args(args)


def main() -> None:
    args = parse_args()
    for file_path in args.files:
        filter_po_file(file_path, args.module, dry_run=args.dry_run)


if __name__ == "__main__":
    main()
