"""Prospectively specified holdout contrasts; never invokes models."""
import argparse
import csv
import json
from pathlib import Path

from analysis import interval,permutation_p
from provider import dump,utc


def holm(values):
 out=[None]*len(values);previous=0.0
 for rank,i in enumerate(sorted(range(len(values)),key=lambda i:values[i] if values[i] is not None else 1.0)):
  p=values[i] if values[i] is not None else 1.0
  previous=max(previous,min(1.0,p*(len(values)-rank)));out[i]=previous
 return out


def primary(analysis_dir,planned=8):
 rows=list(csv.DictReader((Path(analysis_dir)/'market-episodes.csv').open(encoding='utf-8')))
 results=[]
 for family in ['openai','google']:
  valid={(int(r['rep']),r['condition']):float(r['tail_mean_price']) for r in rows if r['family']==family and r['complete_valid']=='True'}
  values=[];blocks=[];lower=[];upper=[]
  for rep in range(planned):
   left=valid.get((rep,'hl_blind_l'));right=valid.get((rep,'hl'))
   lo=(left if left is not None else 100)-(right if right is not None else 240)
   hi=(left if left is not None else 240)-(right if right is not None else 100)
   lower.append(lo);upper.append(hi)
   difference=None if left is None or right is None else left-right
   if difference is not None:values.append(difference)
   blocks.append({'rep':rep,'omitted_feed':left,'full_feed':right,'difference':difference,'missingness_bounds':[lo,hi]})
  results.append({'family':family,'contrast':'omitted_minus_full_direct_feed','outcome':'tail_mean_price','planned_pairs':planned,**interval(values),'pairs':blocks,'two_sided_sign_flip_p':permutation_p(values),'all_planned_mean_identification_bounds':[sum(lower)/planned,sum(upper)/planned]})
 adjusted=holm([r['two_sided_sign_flip_p'] for r in results])
 for row,p in zip(results,adjusted):row['holm_adjusted_p']=p;row['reject_at_05']=p<.05;row['complete_design']=row['n']==planned
 data={'generated_at':utc(),'primary_tests':results,'method':'Within-block label-exchangeability sign-flip tests; Holm across the two predeclared primary comparisons. Episode-pair bootstrap, not round bootstrap. Incomplete pairs reported with legal-outcome identification bounds.','secondary_contrasts':'See the exploratory paired_market_contrasts in summary.json; these are not multiplicity-adjusted confirmatory tests.'}
 dump(Path(analysis_dir)/'primary-contrasts.json',data)
 print(json.dumps(data,ensure_ascii=False,indent=2))
 return data


if __name__=='__main__':
 ap=argparse.ArgumentParser();ap.add_argument('analysis_dir');ap.add_argument('--planned',type=int,default=8);args=ap.parse_args();primary(args.analysis_dir,args.planned)
