#!/usr/bin/env python3
import hashlib,json,pathlib,sys

def check(ok,label):
    if not ok:raise AssertionError(label)

def typed_equal(a,b):
    if type(a) is not type(b):return False
    if isinstance(a,dict):return a.keys()==b.keys() and all(typed_equal(v,b[k]) for k,v in a.items())
    if isinstance(a,list):return len(a)==len(b) and all(typed_equal(x,y) for x,y in zip(a,b))
    return a==b

def verify_loaded(reports,metadata_b,metadata_c,proof):
    check(metadata_b['status']=='pass' and metadata_b['identity']['server_version'].startswith('5.6.'),'local mysql56 metadata')
    check(metadata_c['exit_code']==0 and metadata_c['stderr_bytes']==0 and metadata_c['report']['status']=='pass','dm metadata clean')
    for m in (metadata_b,metadata_c['report']):check(m['business_row_reads']==m['dml']==m['ddl']==0 and m['scope']=='one_table_columns_metadata_only','metadata not business rows')
    check(len(metadata_b['columns'])==16 and len(metadata_c['report']['columns'])==19,'real schema difference retained')
    expected_keys={'one','multi_alias','page_two','star','qualified_star','reserved_alias'}
    unsupported={'distinct','group','having','raw_field','free_alias','write_context'}
    wides=[9007199254740993,9223372036854775807,'18446744073709551615',None]
    amounts=['-12345678901234567890.123456789012345678','0.000000000000000001','99999999999999999999.999999999999999999','0.000000000000000000']
    for framework,r in reports.items():
        check(r['status']=='pass' and r['framework']==framework and r['php']=='7.4.33','actual runtime')
        check(r['scope']=='offline_virtual_contract_compile_and_hydrate_only','limited scope')
        check(r['assertions']==(92 if framework=='store' else 110),'frozen assertion count')
        check(r['os_network_denied'] is True and r['db_queries']==0 and r['guard_negative_denials']==3,'real offline boundary')
        check(r['cache_enabled'] is False and r['http_increment']==0 and r['p0_closed'] is False,'no external completion claim')
        check(len(r['source_identity'])==(3 if framework=='store' else 9),'physical classes complete')
        for info in r['source_identity'].values():check(proof['sources'].get('zhctproject/'+framework+'/'+info['file'])==info['sha256'],'actual source identity')
        check(set(r['compiled'])==expected_keys and set(r['unsupported'])==unsupported,'matrix complete')
        for key,c in r['compiled'].items():
            native=c['native'];projected=c['projected'];p=c['projection']
            check(native['sql'].count(native['field_fragment'])==1 and projected['sql'].count(projected['field_fragment'])==1,'unique projection fragments')
            check(native['sql'].replace(native['field_fragment'],'<projection>',1)==projected['sql'].replace(projected['field_fragment'],'<projection>',1),'only projection changed')
            check(typed_equal(native['bind'],projected['bind']) and typed_equal(native['bind'],{'owned_min':[7,1],'owned_label':['离线"检查',2]}),'named bindings preserved')
            check(hashlib.sha256(projected['sql'].encode()).hexdigest()==c['plan_sql_sha256'],'exact SQL hash')
            check(p['visible']==list(range(len(p['columns']))) and len(p['names'])==len(p['columns'])+len(p['helpers']),'visible plan layout')
            check(p['schema_digest']=='24cf2d7f7cbb3d661bac195bbe51d6f58635481781065cd2ba234ac4d45e05b6','virtual not real schema')
        check(r['compiled']['page_two']['projected']['sql']!=r['compiled']['multi_alias']['projected']['sql'],'pagination separate plan')
        check(all(v['status']=='native_unmodified_not_fixed' for v in r['unsupported'].values()),'unsupported not counted pass')
        check(len(r['thin_model_wire'])==4 and r['float_cast_red_preserved'] is True,'model matrix')
        for i,wire in enumerate(r['thin_model_wire']):
            expected={'id':7,'wide_id':wides[i],'amount':amounts[i],'ratio':1.25,'label':'007','n':'1.20' if i==1 else None}
            check(typed_equal(json.loads(wire),expected),'strict thin model wire contract')
        if framework=='ai_api':
            check(r['actual_metadata_used'] is True and r['gift_schema_provider_reads']==1 and r['offline_connection_allocations']==5,'real constructor metadata context')
            check(len(r['actual_gift_model_wire'])==4,'actual gift model tested')
            for wide,wire in zip(wides,r['actual_gift_model_wire']):check(typed_equal(json.loads(wire),{'log_id':7,'biz_order_id':wide,'money':'1.20','balance_before':'0.00','balance_after':'1.20'}),'actual getter wire')
            c=r['gift_candidate_not_executed'];p=c['projection']
            check(c['schema']['star_allowed'] is False and len(c['schema']['columns'])==19,'real star disabled')
            check(p['names']==['log_id','biz_order_id','money','balance_before','balance_after','cdx_shadow_0','cdx_shadow_1','cdx_shadow_2','cdx_shadow_3'],'actual explicit layout')
            check(c['native']['bind']==c['projected']['bind']=={'owned_min':[0,1]},'actual candidate bind')
            check(c['projected']['sql'].rstrip().endswith('LIMIT 5') and '*' not in c['projected']['sql'],'candidate bounded no star')
            check(hashlib.sha256(c['projected']['sql'].encode()).hexdigest()==c['plan']['sql_sha256'],'actual candidate hash')
        else:check(r['actual_gift_model_wire'] is None and r['gift_candidate_not_executed'] is None,'store not fake real gift coverage')
    return {'status':'pass_limited_offline_only','php':'7.4.33','store_assertions':92,'ai_assertions':110,'projection_pure_assertions':36,'business_rows_read':0,'dml':0,'ddl':0,'cache_tested':False,'actual_select_executed':False,'http_increment':0,'p0_closed':False}

def load(root):
    proof=json.loads((root/'EXECUTION_SHA256.json').read_text())
    for name,sha in proof['prototype'].items():check(hashlib.sha256((root/name).read_bytes()).hexdigest()==sha,'frozen prototype source '+name)
    check(hashlib.sha256((root.parent/'old-driver-shadow-fetch-prototype/ShadowCore.php').read_bytes()).hexdigest()==proof['shadow_core_dependency'],'frozen exact core dependency')
    return ({f:json.loads((root/('offline_'+f+'.json')).read_text()) for f in ('store','ai_api')},json.loads((root/'metadata_B.json').read_text()),json.loads((root/'metadata_C_run.json').read_text()),proof)

if __name__=='__main__':
    try:print(json.dumps(verify_loaded(*load(pathlib.Path(sys.argv[1]))),ensure_ascii=False,indent=2))
    except Exception as e:print(json.dumps({'status':'fail','class':type(e).__name__,'reason':str(e)}));raise SystemExit(1)
