"""Bounded comparison of partitions at the named Flood/Shem/Noah nodes.

Every reversal input is an original duration between selected source nodes.
No previously reversed output is passed to the reversal function.
"""
from pathlib import Path
import hashlib
import json

ROOT=Path('/workspace/scratch/1b40da62dcbd')
OUT=Path(__file__).resolve().parent

def I(n):
    assert isinstance(n,int) and n > 0
    scale=1
    while n % 10 == 0:
        scale*=10
        n//=10
    return scale*int(str(n)[::-1])

checks=[]
def check(label,observed,expected):
    checks.append({'label':label,'observed':observed,'expected':expected,'passed':observed==expected})
    assert observed==expected,label

sources={
    'MT':{'head':14006,'Flood':4836,'Shem':5436,'Noah':6386,'head_role':'Rounded Creation'},
    'LXX':{'head':14896,'Flood':5746,'Shem':6346,'Noah':7296,'head_role':'Rounded Creation, native Cainan'},
    'SP':{'head':13396,'Flood':4716,'Shem':5316,'Noah':6266,'head_role':'Accepted Rounded Fall'},
}
order=('F','S','N','FS','FN','SN','FSN')
expected={
    'MT':[10620,10620,11610,11610,11610,6300,7290],
    'LXX':[9530,10520,16550,10520,16550,12230,12230],
    'SP':[10010,10010,10010,10010,10010,5690,5690],
}
model={}
for tradition,src in sources.items():
    C,F,S,N=(src[k] for k in ('head','Flood','Shem','Noah'))
    check(tradition+' serial lives', [S-F,N-S,N-F], [600,950,1550])
    a,c=F-1406,C-N
    named={'F':F,'S':S,'N':N}
    paths={}
    for label in order:
        nodes=[1406]+[named[n] for n in label]+[C]
        legs=[v-u for u,v in zip(nodes,nodes[1:])]
        inv=list(map(I,legs))
        built=[1406]
        for span in inv: built.append(built[-1]+span)
        paths[label]={'source_path':nodes,'source_legs':legs,'reversed_original_legs':inv,
                      'total':sum(inv),'rebuilt_from_1406':built,
                      'head2':built[-1],'head3':built[-1]+2700}
    check(tradition+' seven named totals',[paths[k]['total'] for k in order],expected[tradition])
    check(tradition+' 1550 lower merge additivity',I(a+1550),I(a)+I(1550))
    check(tradition+' Noah-only equals Flood+Noah',paths['N']['total'],paths['FN']['total'])
    check(tradition+' common lifespan split loss',paths['FN']['total']-paths['FSN']['total'],4320)
    check(tradition+' same loss after Noah-only merge',paths['N']['total']-paths['FSN']['total'],4320)
    check(tradition+' exact inherited stage change',paths['FSN']['head3']-paths['FSN']['head2'],2700)
    dU=I(C-F)-I(1550)-I(c)
    check(tradition+' upper merge law',paths['FN']['total']-paths['F']['total'],-dU)
    model[tradition]={'source':src,'source_four_legs':[a,600,950,c],'paths':paths,
                      '1550_lower_merge_defect':0,'1550_upper_merge_defect':dU,
                      'Noah_partition_minus_primary':paths['N']['total']-paths['F']['total'],
                      'all_nodes_minus_primary':paths['FSN']['total']-paths['F']['total']}

check('shared inverse lifespan values',[I(600),I(950),I(1550)],[600,590,5510])
check('universal 4320 merging defect',I(1550)-I(600)-I(950),4320)
check('MT inherited Flood+Noah head',model['MT']['paths']['FN']['head2'],13016)
check('MT inherited Flood+Shem agreement',model['MT']['paths']['FN']['head2'],model['MT']['paths']['FS']['head2'])
check('LXX refined head equals primary completed head',model['LXX']['paths']['FSN']['head2'],model['LXX']['paths']['F']['head3'])
check('LXX equality coordinate',model['LXX']['paths']['FSN']['head2'],13636)
check('SP Noah partition retains accepted primary',model['SP']['paths']['N']['head2'],11416)
check('SP completed refinement to source',model['SP']['source']['head']-model['SP']['paths']['FSN']['head3'],3600)

actual_pre_noah={
 'MT':[930,912,905,910,895,962,365,969,777],
 'LXX':[930,912,905,910,895,962,365,969,753],
 'SP':[930,912,905,910,895,847,365,720,653],
}
rounded={k:[5*((n+2)//5) for n in v] for k,v in actual_pre_noah.items()}
check('pre-Noah rounded row sums',[sum(rounded[k]) for k in ('MT','LXX','SP')],[7620,7600,7135])
check('SP accepted Fall prefix',[model['SP']['source_four_legs'][-1],sum(rounded['SP'])-5],[7130,7130])
check('MT versus LXX sole rounded prefix difference',[a-b for a,b in zip(rounded['MT'],rounded['LXX'])],[0,0,0,0,0,0,0,0,20])
check('MT/LXX reversal register difference',[I(7620),I(7600),I(7600)-I(7620)],[2670,6700,4030])
check('MT/LXX lower Noah branch preserves910',I(5890)-I(4980),910)
check('MT/LXX Noah inverse head gap',model['LXX']['paths']['N']['head2']-model['MT']['paths']['N']['head2'],4940)
check('MT/LXX full refined head gap',model['LXX']['paths']['FSN']['head2']-model['MT']['paths']['FSN']['head2'],4940)

source_files=[
 'c1433_c1482/evidence/File52c_latest.md',
 'c1433_c1482/agents/sources/File_52a.Inverse_Number_Architecture_Rounded_Chronology_relevant_excerpt.md',
 'project_sources/38-File_18.Chronological_Data_Tables-20260919-141048-.md',
 'project_sources/15-File_22.Cumulative_MT_Harmonics-20260906-202427-.md',
 'project_sources/39-File_51a.Rounded_Scaffold_Mod5_Architecture.md',
 'upload/490d_LXX_Reversed_Spines_and_Accepted_SP_Solution_20260928(1).md',
 'project_sources/03-File_53.Jubilees_22Fold_Creation_Genealogy_Witness-4-.md',
]
record={'status':'PASS','check_count':len(checks),'scope':'Seven named partitions of each of three fixed cumulative source trunks',
        'second_reversal':False,'source_lifespans':{'Noah':950,'Shem':600},
        'actual_pre_noah_lifespans':actual_pre_noah,'rounded_pre_noah_lifespans':rounded,
        'sources':[{'path':p,'sha256':hashlib.sha256((ROOT/p).read_bytes()).hexdigest()} for p in source_files],
        'model':model,'checks':checks}
(OUT/'cumulative_noah_extension.json').write_text(json.dumps(record,indent=2)+'\n')
print(json.dumps({'status':'PASS','checks':len(checks),'model':'cumulative_noah_extension.json'}))
