"""Compact, lossless private-message inventory for disclosed analyst review.

Exact repeated strings are displayed once with all occurrences. No semantic
classification is assigned by this script and no model is invoked.
"""
import argparse
import hashlib
import json
from pathlib import Path


def inventory(run,out):
 run=Path(run);out=Path(out);out.mkdir(parents=True,exist_ok=True);messages={};episodes=[]
 for status in sorted((run/'episodes').glob('*/status.json')):
  s=json.loads(status.read_text(encoding='utf-8'));j=s['job']
  if j['study']!='market':continue
  history=json.loads((status.parent/'market-history.json').read_text(encoding='utf-8')) if (status.parent/'market-history.json').exists() else []
  rows=[]
  for h in history:
   ids=[]
   for sender,a in enumerate(h['actions']):
    message=a['message']
    if message:
     mid=hashlib.sha256(message.encode('utf-8')).hexdigest()[:12]
     if mid in messages and messages[mid]['text']!=message:raise RuntimeError('Short hash collision')
     messages.setdefault(mid,{'id':mid,'text':message,'occurrences':[]})['occurrences'].append({'episode':j['id'],'period':h['period'],'sender':sender})
    else:mid=None
    ids.append(mid)
   rows.append({'period':h['period'],'prices':h['prices'],'messages':ids})
  episodes.append({'episode':j['id'],'family':j['family'],'condition':j['condition'],'status':s['status'],'valid':s.get('metrics',{}).get('valid'),'rows':rows})
 data={'scope':'Every executed market prefix, all nonempty private messages and each price pair. Exact duplicates displayed once with every occurrence. This inventory assigns no semantic labels.','messages':list(messages.values()),'episodes':episodes}
 (out/'review-inventory.json').write_text(json.dumps(data,ensure_ascii=False,indent=2),encoding='utf-8')
 print(json.dumps({'market_episodes':len(episodes),'unique_messages':len(messages),'nonempty_messages':sum(len(m['occurrences']) for m in messages.values())}))


if __name__=='__main__':
 ap=argparse.ArgumentParser();ap.add_argument('run');ap.add_argument('--out',required=True);args=ap.parse_args();inventory(args.run,args.out)
