import json
from pathlib import Path
from decimal import Decimal
P=Path(__file__).resolve().parent
def load(p):return json.loads(p.read_text(),parse_float=Decimal)
def build_tree(dictionary,kind,selected):
    fields=['enum_key','enum_pid','enum_name']+(['set_value'] if kind==10 else [])
    parents={};score=0
    for original in dictionary:
        if int(original['enum_type'])!=kind:continue
        row={k:original[k] for k in fields};key=str(row['enum_key']);pid=str(row['enum_pid']);row['checked']=1 if key in selected else 0
        if kind==10:
            row['recommend']=selected.get(key,'')
            if key in selected:score+=int(row['set_value'])
        if pid=='0': parents[key]=row
        elif pid in parents:parents[pid].setdefault('children',[]).append(row)
    for parent in parents.values():
        if kind==11:parent['checked']=[]
        for child in parent['children']:
            if child['checked']==1:
                if kind==11:parent['checked'].append(child['enum_key'])
                else:parent['checked']=child['enum_key'];parent['recommend']=child['recommend']
    return list(parents.values()),score
out={}
for lane in ['B','C']:
    base=P/'private'/('C' if lane=='C' else '')
    batch=load(base/'batch-before.json');dictionary=batch['dictionary'];results={}
    names=['FOOD_DETAIL1']+(['MEALS_DETAIL1'] if lane=='B' else [])
    for name in names:
        wire=load(base/f'wire-original-{name}.json');actual=json.loads(wire['raw'],parse_float=Decimal)
        if name=='FOOD_DETAIL1':
            tree,_=build_tree(dictionary,11,{'2':'','3':''});expected={'food':tree,'food_allergy':'CDXIW11C8F2_ALLERGY1','other_text':'CDXIW11C8F2_FOOD1','food_Intolerance':'CDXIW11C8F2_INTOLERANCE1','food_disable':'CDXIW11C8F2_DISABLE1'}
        else:
            tree,score=build_tree(dictionary,10,{'2':'CDXIW11C8F2_MEAL2','7':'CDXIW11C8F2_MEAL7'});expected={'meals':tree,'score':score,'other_text':'CDXIW11C8F2_MEALS1'}
        target=actual['data']['detail'];diff=[key for key in set(target)|set(expected) if key not in target or key not in expected or target[key]!=expected[key]]
        assert diff==(['food_Intolerance'] if lane=='C' else []),(lane,name,diff)
        assert wire['before']==wire['after'] and wire['protected_before']==wire['protected_after']
        results[name]={'complete_expected_keys':list(expected),'difference_fields':diff,'status':actual['status'],'expected_intolerance':expected.get('food_Intolerance'),'actual_intolerance':target.get('food_Intolerance'),'tree_exact':'food' not in diff and 'meals' not in diff}
    for name in ['PROBLEM_CREATE','MEALS_CREATE','FOOD_CREATE']:
        wire=load(base/f'wire-original-{name}.json');assert wire['protected_before']==wire['protected_after'];assert wire['protected_before']==batch['protected']
        if (lane=='C' and name!='FOOD_CREATE') or (lane=='B' and name=='PROBLEM_CREATE'):
            assert wire['before']==wire['after']
    events=[json.loads(line,parse_float=Decimal) for line in (base/'pdo-native.jsonl').read_text().splitlines()]
    commits=[e for e in events if e['layer']=='actual PDO.commit'];rollbacks=[e for e in events if e['layer']=='actual PDO.rollBack']
    assert len(rollbacks)==(1 if lane=='B' else 2)
    out[lane]={'read_results':results,'native_commit':len(commits),'native_rollback':len(rollbacks),'retained_original13_exact':True,'original_dictionary_rows':len(dictionary),'recorded_native_events':len(events)}
(P/'first-phase-verification.json').write_text(json.dumps(out,ensure_ascii=False,indent=2)+'\n');print(json.dumps(out,ensure_ascii=False))
