"""Sum per-row rounded amounts from a validated CSV. Python 3.9+."""
import argparse
import csv
from decimal import Decimal, DecimalException, ROUND_HALF_UP, localcontext
import json
import re
import sys


PRICE = re.compile(r"[0-9]{1,9}(?:\.[0-9]{1,4})?")
QUANTITY = re.compile(r"[1-9][0-9]{0,6}")
CENT = Decimal("0.01")
MAX_ROWS = 1_000_000


def summarize(path):
    with localcontext() as context:
        context.prec = 40
        total = Decimal("0.00")
        count = 0
        with open(path, encoding="utf-8-sig", newline="") as source:
            reader = csv.reader(source, strict=True)
            if next(reader, None) != ["unit_price", "quantity"]:
                raise ValueError("header must be unit_price,quantity")
            for record, row in enumerate(reader, start=1):
                if record > MAX_ROWS:
                    raise ValueError("more than 1000000 data records")
                location = f"record {record}, ending at line {reader.line_num}"
                if len(row) != 2:
                    raise ValueError(f"{location}: expected 2 fields")
                price, quantity = row
                if not PRICE.fullmatch(price):
                    raise ValueError(f"{location}: invalid unit_price")
                if not QUANTITY.fullmatch(quantity) or int(quantity) > 1_000_000:
                    raise ValueError(f"{location}: quantity must be 1..1000000")
                amount = (Decimal(price) * int(quantity)).quantize(
                    CENT, rounding=ROUND_HALF_UP
                )
                total += amount
                count += 1
        if not count:
            raise ValueError("at least one data record is required")
        return {"rows": count, "total": format(total, ".2f")}


def main():
    parser = argparse.ArgumentParser(description=__doc__, allow_abbrev=False)
    parser.add_argument("input", help="UTF-8 CSV with unit_price,quantity header")
    args = parser.parse_args()
    try:
        result = summarize(args.input)
    except (OSError, UnicodeError, csv.Error, ValueError, DecimalException) as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        return 1
    print(json.dumps(result))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
