"""Reproduce the published review against source.json; Python standard library only.
Run: python check_roads.py (from any directory). No source data is modified.
"""
from pathlib import Path
import json,hashlib,csv,collections,math
root=Path(__file__).resolve().parent
raw=(root/'source.json').read_bytes(); data=json.loads(raw);meta=json.loads((root/'provenance.json').read_text())
assert hashlib.sha256(raw).hexdigest()==meta['sha256'],'Source differs from recorded snapshot'
features=data['features'];counts=collections.Counter(f['attributes'].get('OID') for f in features)
rows=[]
for f in features:
 a=f['attributes']; reasons=[]; oid=a.get('OID');paths=f.get('geometry',{}).get('paths',[])
 if not str(a.get('NAME') or '').strip():reasons.append('Name review')
 if not oid:reasons.append('Missing identifier')
 elif counts[oid]>1:reasons.append('Repeated identifier')
 if not str(a.get('MTFCC') or '').strip():reasons.append('Missing classification')
 valid=bool(paths) and all(len(p)>=2 and all(len(v)>=2 and all(isinstance(n,(int,float)) and math.isfinite(n) for n in v[:2]) and -180<=v[0]<=180 and -90<=v[1]<=90 for v in p) for p in paths)
 if not valid:reasons.append('Geometry structure')
 elif not any(v!=p[0] for p in paths for v in p[1:]):reasons.append('Zero-length geometry')
 rows.append({'objectid':a['OBJECTID'],'oid':oid,'name':a.get('NAME'),'mtfcc':a.get('MTFCC'),'findings':reasons,'paths':paths})
summary={'total':len(rows),'review':sum(bool(r['findings']) for r in rows),'no_flags':sum(not r['findings'] for r in rows),'findings':dict(collections.Counter(x for r in rows for x in r['findings'])),'classifications':dict(collections.Counter(r['mtfcc'] for r in rows)),'source_sha256':meta['sha256']}
(root/'results.json').write_text(json.dumps({'summary':summary,'records':rows},separators=(',',':')))
with (root/'review.csv').open('w',newline='',encoding='utf-8') as file:
 w=csv.writer(file);w.writerow(['OBJECTID','OID','NAME','MTFCC','review_findings'])
 for r in rows:
  if r['findings']:w.writerow([r['objectid'],r['oid'],r['name'],r['mtfcc'],'; '.join(r['findings'])])
print(json.dumps(summary,indent=2))
