#!/usr/bin/env python3
"""Reproduce the bounded C481 synthesis using exact arithmetic and frozen sources."""
from pathlib import Path
from fractions import Fraction as F
import argparse, hashlib, json

HERE = Path(__file__).resolve().parent
parser = argparse.ArgumentParser()
parser.add_argument("--out", type=Path)
args = parser.parse_args()
d = json.loads((HERE/"INPUT.json").read_text())
manifest = json.loads((HERE/"SOURCE_MANIFEST.json").read_text())
checks = []
def check(name, condition):
    if not condition:
        raise AssertionError(name)
    checks.append(name)

for rec in manifest:
    p = HERE/rec["path"]
    check("source hash: "+rec["path"],
          hashlib.sha256(p.read_bytes()).hexdigest() == rec["sha256"])
for filename, label, needle in d["bindings"]:
    check("source binding: "+label, needle in (HERE/"sources"/filename).read_text())

def inv(n):
    if n == 0: return 0
    zeros = 0
    while n % 10 == 0:
        n //= 10
        zeros += 1
    return int(str(n)[::-1]) * 10**zeros

def triple_core_gain(n):
    # Valid here for n = 10*(100*a+10*b+c), with nonzero outer digits.
    core, trailing = divmod(n,10)
    a, rest = divmod(core,100)
    b, c = divmod(rest,10)
    if trailing or not (1 <= a <= 9 and 1 <= c <= 9):
        raise ValueError("Outside declared three-digit-core domain")
    return 990*(c-a)

r,a = d["rounded"],d["actual"]
E,P,J = [F(*d["ratios"][key]) for key in ("E","P","J")]
parts = {
    "regular_primary":[r["regular_creation"]-r["regular_flood"],
                       r["regular_flood"]-r["conquest"]],
    "regular_noah_refinement":[r["regular_creation"]-r["regular_noah"],
                               r["regular_noah"]-r["regular_flood"],
                               r["regular_flood"]-r["conquest"]],
    "cumulative_primary":[r["cumulative_creation"]-r["cumulative_flood"],
                          r["cumulative_flood"]-r["conquest"]],
    "cumulative_shem_refinement":[r["cumulative_creation"]-r["cumulative_shem"],
                                  r["cumulative_shem"]-r["cumulative_flood"],
                                  r["cumulative_flood"]-r["conquest"]],
    "cumulative_noah_refinement":[r["cumulative_creation"]-r["cumulative_noah"],
                                  r["cumulative_noah"]-r["cumulative_flood"],
                                  r["cumulative_flood"]-r["conquest"]]
}
route_results = {}
for name,values in parts.items():
    route_results[name] = {"input":values,"reversed":[inv(x) for x in values],
                          "sum":sum(inv(x) for x in values),
                          "endpoint":r["conquest"]+sum(inv(x) for x in values)}
A=route_results["regular_primary"]["endpoint"]
check("primary and regular-refined paths meet",
      A == route_results["regular_noah_refinement"]["endpoint"]
        == route_results["cumulative_primary"]["endpoint"] == d["inherited"]["anchor"])
gains = {n:inv(n)-n for n in parts["regular_primary"]+parts["cumulative_primary"]}
check("outer-digit identity explains all primary gains",
      all(g==triple_core_gain(n) for n,g in gains.items()))
check("reversal-derived 8:2 transport",
      A-r["regular_creation"]==8*990 and r["cumulative_creation"]-A==2*990)
check("weighted rounded anchor",
      5*A==4*r["cumulative_creation"]+r["regular_creation"])
deltaC=a["cumulative_creation_completion"]-r["cumulative_creation"]
deltaR=a["regular_creation_completion"]-r["regular_creation"]
check("weighted state-change kernel",4*deltaC+deltaR==0)
check("actual anchor inherited by endpoint pair",
      5*A==4*a["cumulative_creation_completion"]+a["regular_creation_completion"])
check("990 and 989 paired representations",
      r["cumulative_creation"]==A+2*990 and r["regular_creation"]==A-8*990
      and a["cumulative_creation_completion"]==A+2*989
      and a["regular_creation_completion"]==A-8*989 and 989==23*43)
check("known secondary branch",route_results["cumulative_shem_refinement"]["endpoint"]
      ==route_results["cumulative_noah_refinement"]["endpoint"]==A+990)
whole = {k:r["conquest"]+inv(r[k]-r["conquest"])
         for k in ("regular_creation","cumulative_creation")}
check("whole-span operation does not reproduce segmented convergence",
      whole["regular_creation"]!=A and whole["cumulative_creation"]!=A
      and whole["regular_creation"]!=whole["cumulative_creation"])
completed=r["nativity"]+inv(r["conquest"]-r["nativity"])+route_results["regular_primary"]["sum"]
check("Nativity completion",completed==d["inherited"]["completed_anchor"]
      and E*(completed-r["nativity"])==16000)

u={name:F(A-x,23) for name,x in a.items()}
check("all selected actual nodes have integral 23 coordinates",
      all(v.denominator==1 for v in u.values()))
step=a["jared"]-a["noah_gear1"]
check("source-selected 14/15/16 progression",
      step==a["noah_gear1"]-a["flood_gear2"]==598
      and [A-a[name] for name in ("jared","noah_gear1","flood_gear2")]
          ==[step*m for m in (14,15,16)])
conversions={}
for name in ("jared","noah_gear1","flood_gear2"):
    span=A-a[name]
    conversions[name]={key:{"span":ratio*span,"endpoint":A-ratio*span}
                       for key,ratio in (("E",E),("P",P),("J",J))}
check("three calibrated step sizes",J*step==600 and E*step==650)
check("Jared E and Noah P agreement",
      E/P==F(15,14)
      and conversions["jared"]["E"]["endpoint"]
          ==conversions["noah_gear1"]["P"]["endpoint"]==2926)
check("calendar calibration retained",
      336*E==360*P==364*J==F(8400,23))

micro=a["regular_creation_completion"]-a["noah_gear1"]
macro=A-a["exodus"]
check("actual Creation-Noah decomposes as 460 plus 598",
      micro==a["regular_creation_completion"]-a["jared"]+step==460+598==2*23**2)
check("tenfold cross-family placement",macro==10*micro==20*23**2)
Afromactual=a["exodus"]+10*micro
check("same anchor from actual Creation-Noah and Exodus",Afromactual==A)
relation=4*a["cumulative_creation_completion"]-49*a["regular_creation_completion"]+50*a["noah_gear1"]-5*a["exodus"]
check("combined source linear constraint",relation==0)
small=[F(micro)*E**k for k in range(3)]
large=[F(macro)*E**k for k in range(3)]
check("C480 duration sequence retained",small==list(map(F,d["inherited"]["C480_widths"]))
      and [b-c for c,b in d["inherited"]["C480_intervals"]]==d["inherited"]["C480_widths"])
check("homogeneous scale intertwines the expansions",large==[10*v for v in small])

first=[A-E*(A-a[key]) for key in ("regular_creation_completion","noah_gear1")]
second=[A-E*(A-x) for x in first]
check("bounded endpoint pressure check",
      first==[3426,2276] and second[0]-second[1]==1250
      and [x%1 for x in second]==[F(4,23),F(4,23)])
mirror_q=[F(A-1)-w for w in large]
check("source-declared Rounded Mirror completion",mirror_q==[1445,525,-475])
def show_rounded(q):
    return ("AD "+str(q+1)) if q>0 else (str(1-q)+" BC" if q<0 else "origin")
outputs={
 "step":"C481","status":"PASS","checks":checks,
 "source_hashes":{x["path"]:x["sha256"] for x in manifest},
 "source_routes":route_results,"decimal_gains":gains,
 "shared_anchor":A,"actual_reconstruction":Afromactual,
 "state_change":{"cumulative":deltaC,"regular":deltaR,"weighted_residual":4*deltaC+deltaR},
 "actual_23_coordinates":u,"conversions":conversions,
 "secondary_branch":route_results["cumulative_shem_refinement"]["endpoint"],
 "whole_span_countercomparison":whole,
 "Nativity_anchor":completed,"linear_constraint_residual":relation,
 "small_ladder":small,"large_ladder":large,
 "same_anchor_first_pair":first,"same_anchor_second_pair_diagnostic":second,
 "Rounded_Mirror_q":mirror_q,"Rounded_Mirror_displays":[show_rounded(q) for q in mirror_q],
 "scope_note":"Retrospective source-conditioned synthesis. No target scan rerun, historical-probability claim, or inverse-of-the-inverse research."
}
def serialize(x):
    if isinstance(x,F): return x.numerator if x.denominator==1 else f"{x.numerator}/{x.denominator}"
    if isinstance(x,dict): return {str(k):serialize(v) for k,v in x.items()}
    if isinstance(x,list): return [serialize(v) for v in x]
    return x
text=json.dumps(serialize(outputs),indent=2,ensure_ascii=False)+"\n"
if args.out: args.out.write_text(text)
print(json.dumps({"status":"PASS","checks":len(checks),"source_hash_checks":len(manifest),
                  "source_bindings":len(d["bindings"]),"anchor":A,"actual_reconstruction":Afromactual,
                  "small_ladder":serialize(small),"large_ladder":serialize(large),
                  "mirror":outputs["Rounded_Mirror_displays"]},indent=2))

