import json
from pathlib import Path

def exact(a,b):
    assert type(a) is type(b)
    if isinstance(a,dict):
        assert a.keys()==b.keys()
        for key in a:exact(a[key],b[key])
    elif isinstance(a,list):
        assert len(a)==len(b)
        for x,y in zip(a,b):exact(x,y)
    else:assert a==b

def tree(rows,parent=0):
    out=[]
    for row in rows:
        assert type(row['id']) is type(row['pid']) is type(row['level']) is int
        assert row['name'].startswith('CDXCITY10')
        if row['pid']!=parent:continue
        item=dict(row);children=tree(rows,row['id'])
        if children:item['children']=children
        item['chhildShow']=False;out.append(item)
    return out

def verify(b,c,result):
    assert result['status']=='pass' and result['http_pairs']==2
    for lane,data in [('B',b),('C',c)]:
        r=result['lanes'][lane]
        assert r['status']=='pass' and r['source_rows']==4
        assert r['http_business_dml']==r['ddl']==r['actor_database_writes']==0
        assert r['warnings']==(0 if lane=='B' else 2)
        if lane=='C':assert r['warning_fingerprints']==['cf8ef79b152baacf4b5fed5aaa4e42947f6b4a70c624ae64687b4bb2b6d5f593']*2
        assert r['natural_rows_before_fixture']==0 and r['fixture_inserts']==r['fixtures_retained']==4
        assert r['natural_unchanged'] and r['worker_stopped'] and not r['port_listening']
        assert r['ordinary_auth_used'] and not r['real_login_tested']
        assert r['request_end_count']==len(r['cases'])==len(data['responses'])==2
        assert len(data['source'])==4 and len({x['id'] for x in data['source']})==4
        expected={'code':0,'message':'','data':tree(data['source'])}
        assert expected['data'] and len(expected['data'])==1
        for response,case in zip(data['responses'],r['cases']):
            assert case['method']=='POST' and case['path']=='/p/city/lists' and case['http']==200
            assert case['full_original_tree_type_value_order_equal']
            raw=json.loads(response['raw']);raw.pop('trace_id',None)
            exact(raw,response['body']);exact(response['body'],expected)
    exact(b['source'],c['source'])
    for x,y in zip(b['responses'],c['responses']):exact(x['body'],y['body'])
    return {'status':'pass','http_pairs':2,'owned_rows_each':4,'new_actual_methods':1,'full_type_value_tree_order_equal':True,'SQL_fingerprint_gate_closed':False}

if __name__=='__main__':
    p=Path(__file__).parent
    print(json.dumps(verify(*(json.loads((p/f).read_text()) for f in ['evidence-B.json','evidence-C.json','results.json']))))
