#!/usr/bin/env python3
from __future__ import annotations

from pathlib import Path
import sys


def load_annotations(path: Path) -> dict[str, str]:
    annotations: dict[str, str] = {}
    for lineno, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
        line = raw.strip()
        if not line or line.startswith("#"):
            continue
        try:
            target, comment = raw.split("\t", 1)
        except ValueError as exc:
            raise SystemExit(f"{path}:{lineno}: expected '<vapi signature> TAB <comment>'") from exc
        target = target.strip()
        comment = comment.strip()
        if not target or not comment.startswith("// PHPEF "):
            raise SystemExit(f"{path}:{lineno}: invalid annotation row")
        annotations[target] = comment
    if not annotations:
        raise SystemExit(f"{path}: no annotations configured")
    return annotations


def annotate_vapi(vapi: Path, stamp: Path, annotations_path: Path, missing_label: str) -> None:
    annotations = load_annotations(annotations_path)
    comment_values = set(annotations.values())
    out: list[str] = []
    inserted = {target: False for target in annotations}
    tab = "\t"

    for line in vapi.read_text(encoding="utf-8").splitlines():
        stripped = line.strip()
        if stripped in comment_values:
            continue
        if stripped in annotations and not inserted[stripped]:
            out.append(tab + annotations[stripped])
            inserted[stripped] = True
        out.append(line)

    missing = [target for target, done in inserted.items() if not done]
    if missing:
        raise SystemExit(
            f"could not find {missing_label} target(s) in {vapi}: " + ", ".join(missing)
        )

    vapi.write_text("\n".join(out) + "\n", encoding="utf-8")
    stamp.write_text(f"annotated {vapi}\n", encoding="utf-8")


def main(argv: list[str]) -> int:
    if len(argv) != 5:
        raise SystemExit(
            "usage: annotate_vapi_comments.py <vapi> <stamp> <annotations.tsv> <missing-label>"
        )
    annotate_vapi(Path(argv[1]), Path(argv[2]), Path(argv[3]), argv[4])
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))
