#!/usr/bin/env python3
"""Exact finite-rule analysis. Synthetic uniform answers, never visitor data."""
import json,itertools,collections,math,argparse
from pathlib import Path
R=Path(__file__).resolve().parents[1];out={}
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--input',type=Path);parser.add_argument('--output',type=Path);args=parser.parse_args()
if args.input:
 quizzes=json.loads(args.input.read_text())
else:
 quizzes=[json.loads(p.read_text()) for p in sorted((R/'data/legacy/quizzes').glob('*.json'))]
 if not quizzes:raise SystemExit('Supply --input legacy-rule-inputs.json --output counts.json')
 inputs=[{k:q[k] for k in ['slug','type','questions','results']} for q in quizzes if q['type']!='input']
 (R/'static/research/legacy-rule-inputs.json').write_text(json.dumps(inputs,indent=2)+'\n')
for q in quizzes:
 if q['type']=='input':continue
 questions=q['questions'];total=math.prod(len(x['options']) for x in questions) if hasattr(math,'prod') else 4**len(questions)
 counts=collections.Counter();ties=0;score_counts=collections.Counter()
 if q['type']=='scored':
  score_counts[0]=1
  for x in questions:
   nxt=collections.Counter()
   for value,n in score_counts.items():
    for o in x['options']:nxt[value+int(o['type'])]+=n
   score_counts=nxt
  maximum=max(score_counts);n=len(q['results'])
  for i,r in enumerate(q['results']):
   low=i*(maximum+1)//n;high=(i+1)*(maximum+1)//n-1
   counts[r['key']]=sum(v for k,v in score_counts.items() if low<=k<=high)
 else:
  for choices in itertools.product(*[[o['type'] for o in x['options']] for x in questions]):
   tally={}
   for key in choices:tally[key]=tally.get(key,0)+1
   best=max(tally.values());leaders=[k for k in tally if tally[k]==best];ties+=len(leaders)>1;counts[leaders[0]]+=1
 assert sum(counts.values())==total
 out[q['slug']]={'method':'All answer combinations, each option equally weighted; exact enumeration/dynamic programming. This is not a population percentile or visitor result distribution.','combinations':total,'result_counts':dict(counts),'ties':ties,'score_counts':dict(score_counts),'questions':len(questions),'result_labels':{r['key']:r['title'] for r in q['results']}}
(args.output or R/'static/research/legacy-rule-analysis.json').write_text(json.dumps(out,indent=2)+'\n');print('Measured',len(out),'quiz rules')
