#!/usr/bin/env python3
import json,re,sys,hashlib
from pathlib import Path
story_path=Path(sys.argv[1]);outline_path=Path(sys.argv[2]);story=json.loads(story_path.read_text());outline=json.loads(outline_path.read_text());errs=[];rows=[]
if story.get('outline_sha256')!=hashlib.sha256(outline_path.read_bytes()).hexdigest():errs.append('outline_sha_mismatch')
sp={x['part']:x for x in story.get('parts',[])}
for op in outline.get('parts',[]):
 part=op['part'];sps=sp.get(part,{}).get('paragraphs',[])
 if len(sps)!=12:errs.append(f'P{part}_paragraph_count');continue
 for beat,para in zip(op['paragraphs'],sps):
  text=para if isinstance(para,str) else para.get('text') or para.get('narration') or ''
  rows.append({'location':f"P{part}D{beat['paragraph']}",'text_words':len(re.findall(r'\b\w+\b',text,re.UNICODE)),'evidence_ids':beat.get('evidence_ids',[]),'authority_ids':beat.get('authority_ids',[]),'continuity_in':beat.get('continuity_in'),'continuity_out':beat.get('continuity_out')})
  if len(re.findall(r'\b\w+\b',text,re.UNICODE))<45:errs.append(f"P{part}D{beat['paragraph']}_too_short")
# Canonical outline itself must carry each evidence and authority into at least one prose location.
e={f'E{i:02d}':[] for i in range(1,10)};a={f'A{i:02d}':[] for i in range(1,7)}
for r in rows:
 for x in r['evidence_ids']:e[x].append(r['location'])
 for x in r['authority_ids']:a[x].append(r['location'])
for x,v in {**e,**a}.items():
 if not v:errs.append(f'{x}_unplaced')
out={'status':'passed' if not errs else 'failed','story_sha256':hashlib.sha256(story_path.read_bytes()).hexdigest(),'outline_sha256':hashlib.sha256(outline_path.read_bytes()).hexdigest(),'locations_checked':len(rows),'evidence_placement':e,'authority_placement':a,'errors':errs};print(json.dumps(out,ensure_ascii=False));raise SystemExit(1 if errs else 0)
