"""What each engine adds to the fan-out, from the public panel: leave-one-out reach, what the merged list is made of."""
import pickle, sys, os, json, itertools, collections, statistics
HERE = os.path.dirname(os.path.abspath(__file__))
D = os.environ.get('JEVLIN_PANEL_DIR', os.path.join(HERE, 'panel'))  # a checkout of the supersearch-tests dataset
sys.path.insert(0, D)
import score
items, calls = pickle.load(open(os.path.join(D, 'panel.pkl'), 'rb'))
E = ['exa', 'brave', 'parallel-search', 'perplexity-search']
def found(a, i, t):
    r = calls[a].get((i, 1, t))
    return None if r is None else bool(score.match_rank(score.dedupe([u for u in r['urls'] if u]), items[i], 'exact'))
def reach(arms):
    per = {}
    for i in items:
        v = []
        for t in (1, 2, 3):
            f = [found(a, i, t) for a in arms]
            if None in f: continue
            v.append(1.0 if any(f) else 0.0)
        if v: per[i] = statistics.mean(v)
    return per
full = reach(E); out = {'reach_all_four': round(100 * statistics.mean(full.values()), 1), 'leave_one_out': {}, 'alone': {}, 'pairs': {}}
for a in E:
    r = reach([e for e in E if e != a]); d = score.boot_diff(full, r)
    out['leave_one_out'][a] = dict(reach_without=round(100 * statistics.mean(r.values()), 1), lost=d['mean'], ci=d['ci'], questions_lost=d['wins'])
    out['alone'][a] = round(100 * statistics.mean(reach([a]).values()), 1)
for a, b in itertools.combinations(E, 2): out['pairs'][a + '+' + b] = round(100 * statistics.mean(reach([a, b]).values()), 1)
# what the live balanced merged list is made of (first 10 shown), phrasing 1, trials 1-3
slots = collections.Counter(); votes = collections.Counter(); n = 0; gold_votes = collections.Counter(); gold_rank_by_votes = collections.defaultdict(list)
for i, it in items.items():
    for t in (1, 2, 3):
        r = calls['balanced'].get((i, 1, t))
        if not r: continue
        for j, (u, fb, v) in enumerate(list(zip(r['urls'], r['found_by'], r['votes']))[:10]):
            n += 1; nv = len(set(fb)); votes[min(nv, 4)] += 1
            for e in set(fb): slots[e] += 1
            if score.match_rank([u], it, 'exact'): gold_votes[min(nv, 4)] += 1
out['balanced_top10'] = dict(slots=n, share_with_engine={e: round(100 * c / n, 1) for e, c in slots.most_common()}, by_engines_agreeing={str(k): round(100 * v / n, 1) for k, v in sorted(votes.items())},
                             answer_pages_by_engines_agreeing={str(k): v for k, v in sorted(gold_votes.items())})
json.dump(out, open(os.path.join(D, 'fanout.json'), 'w'), indent=1); print(json.dumps(out, indent=1))
