"""Build a deterministic catalog using only the Python standard library."""
import argparse
import csv
import hashlib
import json
from pathlib import Path
import sys

ROOT = Path(__file__).resolve().parents[1]


def build(source, target):
    with source.open(encoding="utf-8", newline="") as stream:
        reader = csv.DictReader(stream)
        if reader.fieldnames != ["id", "label"]:
            raise ValueError("header must be id,label")
        rows, seen = [], set()
        for row in reader:
            if set(row) != {"id", "label"} or not row["id"] or not row["label"]:
                raise ValueError("each row needs exactly one nonempty id and label")
            if row["id"] in seen:
                raise ValueError("duplicate id: " + row["id"])
            seen.add(row["id"])
            rows.append({"id": row["id"], "label": row["label"]})
    payload = (json.dumps(sorted(rows, key=lambda r: r["id"]),
                          ensure_ascii=False, separators=(",", ":")) + "\n").encode("utf-8")
    target.parent.mkdir(parents=True, exist_ok=True)
    target.write_bytes(payload)
    return payload


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", type=Path, default=ROOT / "data/labels.csv")
    parser.add_argument("--output", type=Path, default=ROOT / "build/catalog.json")
    args = parser.parse_args()
    try:
        payload = build(args.input, args.output)
    except (OSError, ValueError) as error:
        print(str(error), file=sys.stderr)
        return 2
    print(json.dumps({"built": str(args.output), "bytes": len(payload),
                      "sha256": hashlib.sha256(payload).hexdigest()}))
    return 0


if __name__ == "__main__":
    sys.exit(main())
