"""Keyed reconciliation of fixed JSON fixtures. No database or CDC stream tested."""
import copy,json
from pathlib import Path
P=Path(__file__).resolve().parent
source=[{'id':i,'amount_cents':i*100,'status':'active'if i%2 else 'closed'}for i in range(1,7)]
cases={'exact':copy.deepcopy(source),'changed_amount':copy.deepcopy(source),'replaced_key':copy.deepcopy(source),'duplicate_key':copy.deepcopy(source),'normalized_status':copy.deepcopy(source),'numeric_string':copy.deepcopy(source)}
cases['changed_amount'][2]['amount_cents']=301
cases['replaced_key'][-1]['id']=7
cases['duplicate_key'][-1]=copy.deepcopy(source[-2])
for row in cases['normalized_status']:row['status']=' '+row['status'].upper()+' '
cases['numeric_string'][0]['amount_cents']='100'
def index(rows):
 d={};duplicates=[];invalid=[]
 for row in rows:
  key=row['id']
  if type(key)is not int or type(row['amount_cents'])is not int or not isinstance(row['status'],str):
   invalid.append(key);continue
  status=row['status'].strip().lower()
  if status not in {'active','closed'}:invalid.append(key);continue
  if key in d:duplicates.append(key)
  d[key]=(row['amount_cents'],status)
 return d,duplicates,invalid
expected,_,_=index(source);out={}
for name,rows in cases.items():
 actual,duplicates,invalid=index(rows)
 missing=sorted(set(expected)-set(actual));extra=sorted(set(actual)-set(expected));changed=sorted(k for k in set(expected)&set(actual)if expected[k]!=actual[k])
 out[name]={'sourceRows':len(source),'targetRows':len(rows),'countEqual':len(source)==len(rows),'duplicateKeys':duplicates,'invalidKeys':invalid,'missingKeys':missing,'unexpectedKeys':extra,'changedKeys':changed,'reconciled':not any([duplicates,invalid,missing,extra,changed])}
assert all(r['countEqual']for r in out.values())
assert [k for k,r in out.items()if r['reconciled']]==['exact','normalized_status']
assert out['changed_amount']['changedKeys']==[3]
assert out['replaced_key']['missingKeys']==[6] and out['replaced_key']['unexpectedKeys']==[7]
assert out['duplicate_key']['duplicateKeys']==[5]
assert out['numeric_string']['invalidKeys']==[1]
(P/'fixtures.json').write_text(json.dumps({'source':source,'targets':cases},indent=2)+'\n')
(P/'results.json').write_text(json.dumps({'scope':'Six fixed target snapshots. Exact integer cents; status trim/lower explicitly permitted. No database, CDC, timing or production cutover tested.','cases':out,'countChecksPassed':6,'reconciledCases':2},indent=2)+'\n')
print(json.dumps(out,indent=2))
