"""Add listed synthetic equipment masses; unknowns never become zero totals."""
from decimal import Decimal, InvalidOperation
import json
from pathlib import Path


def amount(value):
    if not isinstance(value, str):
        raise ValueError("Masses must be decimal strings or null")
    try:
        number = Decimal(value)
    except InvalidOperation as error:
        raise ValueError("Invalid decimal") from error
    if not number.is_finite() or number < 0:
        raise ValueError("Masses must be finite and nonnegative")
    return number


def evaluate(data):
    cases = data["cases"]
    if not isinstance(cases, list) or not cases:
        raise ValueError("Nonempty case list required")
    rows, case_ids = [], set()
    for case in cases:
        ident = case["id"]
        if not isinstance(ident, str) or not ident or ident in case_ids:
            raise ValueError("Unique nonempty case IDs required")
        case_ids.add(ident)
        modules = case["modules"]
        if not isinstance(modules, list) or not modules:
            raise ValueError("Nonempty module list required")
        known = Decimal(0)
        bag_known = Decimal(0)
        missing, bag_missing, seen = [], [], set()
        for module in modules:
            name = module["id"]
            if not isinstance(name, str) or not name or name in seen:
                raise ValueError("Unique nonempty module IDs required")
            seen.add(name)
            if type(module["in_bag"]) is not bool:
                raise ValueError("in_bag must be boolean")
            if module["kg"] is None:
                missing.append(name)
                if module["in_bag"]:
                    bag_missing.append(name)
            else:
                value = amount(module["kg"])
                known += value
                if module["in_bag"]:
                    bag_known += value
        rows.append({"id": ident, "known_equipment_subtotal_kg": format(known, ".2f"),
                     "listed_equipment_total_kg": None if missing else format(known, ".2f"),
                     "known_bag_subtotal_kg": format(bag_known, ".2f"),
                     "listed_bag_total_kg": None if bag_missing else format(bag_known, ".2f"),
                     "missing_masses": missing, "complete_carried_load_kg": None})
    return {"basis": "invented inputs; output rounded to two decimal places",
            "scope": "listed equipment only; no adequacy, capacity or readiness verdict",
            "excluded": data["excluded"], "rows": rows}


if __name__ == "__main__":
    print(json.dumps(evaluate(json.loads(Path(__file__).with_name("inputs.json").read_text(encoding="utf-8"))), indent=2))
