"""Replay Treg's unchanged pure settlement modules using synthetic provider data.

Usage: python settlement-probe.py /path/to/treg-checkout
No server, ledger, credentials, or provider calls are involved.
"""
import hashlib
import importlib
import json
import math
from pathlib import Path
import platform
import sys
import types

PIN = "5b8b8cdca5ca90709093b8ee197639da907deb98"
root = Path(sys.argv[1]).resolve() / "src"
digests = {
    "treg/domain/asynctasks/__init__.py": "b391d9fb7cc3b94208b7e3f2064b43b65375d0c4dcb67f48ae5476fea77cfcce",
    "treg/domain/money/settlement.py": "76910666f7194f24d7124a7a379a1e3d23ca53fedd8a2879da778bc837861404",
}
for path, digest in digests.items():
    assert hashlib.sha256((root / path).read_bytes()).hexdigest() == digest, path
# Bypass unrelated package initializers which load server/database dependencies.
# These namespace containers contain no replacement functions or business rules.
for name in ("treg", "treg.domain", "treg.domain.money"):
    package = types.ModuleType(name)
    package.__path__ = [str(root / name.replace(".", "/"))]
    sys.modules[name] = package
s = importlib.import_module("treg.domain.money.settlement")

cost = {
    "settle": "usage",
    "table": [{"when": {"body.size": "small"}, "value": 0.10}],
    "fallback": {"value": 2.0},
    "usage": {"unit": "usd", "terms": [
        {"path": "usage.input", "rate": 0.000002},
        {"path": "usage.output", "rate": 0.000010},
        {"path": "usage.details[modality=IMAGE].count", "rate": 0.000100},
    ]},
}
basis = s.derive_basis(cost, request={"body": {"size": "small"}},
                       input_schema={}, unit_micro=1_000_000, terminal=True)
print(f"Python {platform.python_version()}; source {PIN}")
print(f"reserve={basis['reserve_micro']}; fallback={basis['fallback_micro']}; unit=micro-USD")
assert basis["reserve_micro"] == 100_000 and basis["fallback_micro"] == 2_000_000
cases = [
    ("missing", {}, None, 100_000),
    ("explicit_zero", {"input": 0}, 0.0, 0),
    ("partial", {"input": 40}, 0.000080, 80),
    ("decimal_string", {"input": "40.0"}, 0.000080, 80),
    ("invalid_present", {"input": 40, "output": -1}, None, 100_000),
    ("boolean_present", {"input": True}, None, 100_000),
    ("nonfinite_present", {"input": float("inf")}, None, 100_000),
    ("above_reserve", {"output": 30_000}, 0.30, 300_000),
    ("image_second", {"details": [{"modality": "TEXT", "count": 999},
                                   {"modality": "IMAGE", "count": 2}]}, 0.0002, 200),
    ("duplicate_image", {"details": [{"modality": "IMAGE", "count": 2},
                                      {"modality": "IMAGE", "count": 9}]}, 0.0002, 200),
]
for name, usage, expected_usage, expected_micro in cases:
    evidence = {"terminal": {"usage": usage}}
    observed = s.usage_evidence(basis, evidence)
    actual = s.settle(basis, evidence)
    assert (observed is None if expected_usage is None else
            observed is not None and math.isclose(observed, expected_usage, rel_tol=1e-12)), (name, observed)
    assert actual == expected_micro, (name, actual)
    print(f"{name}: observed={observed!r}; settled={actual}")

# The worker serializes the basis into its pending task. Exercise this value
# boundary; this is not a database persistence or worker integration test.
saved = json.loads(json.dumps(basis))
cost["usage"]["terms"][0]["rate"] = 0.9
assert s.settle(saved, {"terminal": {"usage": {"input": 40}}}) == 80
print("serialized_basis_after_catalog_edit: settled=80")
credit = s.derive_basis(
    {"settle": "usage", "usage": {"path": "usage.credits", "unit": "credit"},
     "fallback": {"value": 0.10}}, request={}, input_schema={},
    unit_micro=1_000_000, terminal=True)
assert s.usage_evidence(credit, {"terminal": {"usage": {"credits": 7}}}) == 7
assert s.settle(credit, {"terminal": {"usage": {"credits": 7}}}) == 100_000
print("unrated_credit_meter: observed=7.0; settled=100000")
print("PASS: 12 synthetic cases; pure modules only; no ledger or provider validation")
