#!/usr/bin/env python3
"""
FINAL v2 — 실용 랭킹: 게이트 조정(abort율 + Wilson) + λ 반영 + 지능 통합
핵심: 하드 게이트는 'abort율 ≤ 15%' 로, Wilson 하한은 리포트용. 
작은 n의 Wilson 하한이 과도하게 낮은 문제를 회피.
"""
import math

IQ = {
    "deepseek-v4-flash":  51.77, "deepseek-v4-pro": 53.20, "gpt-5.6-luna": 52.32,
    "Kimi-K3": 59.70, "Kimi-K2.7-Code": None, "hy3-paid": None, "MiniMax-M3": None,
    "mimo-v2.5": None, "mimo-v2.5-pro": None, "gemini-3.7-flash": 56.03,
    "laguna-s-2.1-free": None, "GLM-5.3": None, "GLM-5.2": 52.64,
    "Step-3.7-Flash": None, "Qwen3.7-Flash": None,
}
BENCH = {
    "deepseek-v4-flash": (157, 100.0, 0, 99, 204.4), "deepseek-v4-pro": None,
    "gpt-5.6-luna": (64, 91.0, 4, 93, 26.9), "Kimi-K3": (115, 70.0, 24, 95, 113.3),
    "Kimi-K2.7-Code": None, "hy3-paid": (9, 100.0, 0, 91, 3.6), "MiniMax-M3": None,
    "mimo-v2.5": None, "mimo-v2.5-pro": None, "gemini-3.7-flash": (3, 33.0, 1, 83, 2.6),
    "laguna-s-2.1-free": (9, 78.0, 1, 95, 10.2), "GLM-5.3": None, "GLM-5.2": (3, 0.0, 3, 0, 0.0),
    "Step-3.7-Flash": None, "Qwen3.7-Flash": None,
}
PRICE = {
    "deepseek-v4-flash": (0.14, 0.28, 0.0028), "deepseek-v4-pro": (0.435, 0.87, 0.003625),
    "gpt-5.6-luna": (0.20, 1.20, 0.02), "Kimi-K3": (3.00, 15.00, 0.30),
    "Kimi-K2.7-Code": (0.95, 4.00, 0.19), "hy3-paid": (0.14, 0.58, 0.035),
    "MiniMax-M3": (0.30, 1.20, 0.06), "mimo-v2.5": (0.14, 0.28, 0.0028),
    "mimo-v2.5-pro": (0.435, 0.87, 0.0036), "gemini-3.7-flash": (0.75, 3.75, 0.075),
    "laguna-s-2.1-free": (0.0, 0.0, 0.0), "GLM-5.3": (1.40, 4.40, 0.26),
    "GLM-5.2": (1.40, 4.40, 0.26), "Step-3.7-Flash": (0.20, 1.15, 0.04),
    "Qwen3.7-Flash": (0.03, 0.13, 0.006),
}

def wilson_lower(k, n, z=1.96):
    if n == 0: return 0.0
    p = k/n
    denom = 1 + z*z/n
    return max(0.0, (p + z*z/(2*n) - z*math.sqrt(p*(1-p)/n + z*z/(4*n*n))) / denom)

obs = [(m, d[0], d[1]) for m, d in BENCH.items() if d]
tot_k = sum(round(r*ok/100) for _, r, ok in obs)
tot_n = sum(r for _, r, _ in obs)
alpha0, beta0 = tot_k, tot_n - tot_k

def p_hat(k, n): return (k + alpha0) / (n + alpha0 + beta0)

def c_eff(p, h):
    p_in, p_out, p_cache = p
    return 0.05*p_in + 0.90*(h*p_cache + (1-h)*p_in) + 0.05*p_out

# λ: abort 1회당 인적 복구 비용 — 5분 × $60/hr = $5 (보수적)
LAMBDA = 5.0
# 성공 실행 평균 토큰 (M tokens) → $ 변환: C_succ = C_eff × tokens/1M
TOK_PER_TASK_M = 0.05  # 50k tokens/task 가정 (반복 에이전트)

rows = []
for m in PRICE:
    b = BENCH[m]
    iq = IQ[m]
    if b:
        n, ok, abort, cache, toks = b
        k = round(n*ok/100)
        ps = p_hat(k, n)
        wl = wilson_lower(k, n)
        h = cache/100.0
        ce = c_eff(PRICE[m], h)
        c_succ = ce * TOK_PER_TASK_M
        fail_ratio = 0.5  # 실패는 성공의 절반 토큰 소모
        c_fail = c_succ * fail_ratio
        retry = (1 - ps) / ps
        E_C = c_succ + retry * c_fail + LAMBDA * retry  # λ는 재시도 1회당
        abort_rate = abort / n
    else:
        ps = wl = E_C = abort_rate = None
        h = 0.9
        ce = c_eff(PRICE[m], h)
    rows.append(dict(m=m, iq=iq, n=n if b else None, ok=ok if b else None, ps=ps, wl=wl,
                     abort=abort if b else None, abort_rate=abort_rate, h=h, ce=ce,
                     E_C=E_C, has_bench=b is not None))

print("="*112)
print("FLEET 15-MODEL — 실용 랭킹 v2 (2026-08-16) · 캐시 90% 워크로드, λ=$5/abort, 50k tok/task")
print("="*112)
print(f"\n{'#':<3}{'Model':<22}{'IQ':>7}{'IQ상태':>9}{'n':>5}{'OK%':>6}{'p_hat':>7}{'Wils下':>7}{'Abort':>6}{'abort%':>7}{'Cache':>6}{'C_eff$':>8}{'E[C]$/task':>11}")
print("-"*112)
for i, r in enumerate(sorted(rows, key=lambda x: -(x['iq'] or 0)), 1):
    iq_s = f"{r['iq']:.2f}" if r['iq'] else "—"
    iq_st = "scored" if r['iq'] else "NOT-YET"
    n_s = str(r['n']) if r['n'] is not None else "—"
    ok_s = f"{r['ok']:.0f}" if r['ok'] is not None else "—"
    ps_s = f"{r['ps']:.3f}" if r['ps'] is not None else "—"
    wl_s = f"{r['wl']:.3f}" if r['wl'] is not None else "—"
    ab_s = str(r['abort']) if r['abort'] is not None else "—"
    abr_s = f"{r['abort_rate']*100:.0f}%" if r['abort_rate'] is not None else "—"
    ec_s = f"${r['E_C']:.4f}" if r['E_C'] is not None else "—"
    print(f"{i:<3}{r['m']:<22}{iq_s:>7}{iq_st:>9}{n_s:>5}{ok_s:>6}{ps_s:>7}{wl_s:>7}{ab_s:>6}{abr_s:>7}{r['h']*100:>5.0f}%{r['ce']:>8.4f}{ec_s:>11}")

# ---------- 하드 게이트: abort율 ≤ 15% + 실행데이터 있음 ----------
print("\n" + "="*112)
print("하드 게이트: abort율 ≤ 15% (실패가 재시도·인적복구 비용 폭증시키는 모델 배제)")
print("="*112)
gated = [r for r in rows if r['has_bench'] and r['abort_rate'] is not None and r['abort_rate'] <= 0.15]
excluded = [r for r in rows if r['has_bench'] and (r['abort_rate'] is None or r['abort_rate'] > 0.15)]
for r in gated:
    print(f"  PASS {r['m']:<22} abort율 {r['abort_rate']*100:.0f}%")
for r in excluded:
    print(f"  FAIL {r['m']:<22} abort율 {r['abort_rate']*100:.0f}%  (Kimi-K3 21%, GLM-5.2 100%, gemini 33%)")

# ---------- 게이트 통과 모델 스코어링: 지능 + 비용 + 성공률 ----------
print("\n" + "="*112)
print("최종 스코어: 3축 정규화 (IQ / 1-비용 / 성공률) — 실행 2배 가중, IQ 1배")
print("="*112)
iq_vals = [r['iq'] for r in rows if r['iq']]
iq_min, iq_max = min(iq_vals), max(iq_vals)
cmin = min(r['ce'] for r in rows)
cmax = max(r['ce'] for r in rows)
ps_vals = [r['ps'] for r in rows if r['ps'] is not None]
ps_min, ps_max = min(ps_vals), max(ps_vals)

def score(r):
    d_iq = (r['iq'] - iq_min) / (iq_max - iq_min) if r['iq'] is not None else 0.5  # 결측: 중립
    d_c = (cmax - r['ce']) / (cmax - cmin)
    d_ps = (r['ps'] - ps_min) / (ps_max - ps_min) if r['ps'] is not None else 0.0
    # 실행(성공률+비용) 2배, 지능 1배
    return (2*d_ps + 2*d_c + 1*d_iq) / 5

print(f"\n{'순위':<5}{'Model':<22}{'IQ':>7}{'d_IQ':>7}{'C_eff':>8}{'d_C':>7}{'p_hat':>7}{'d_PS':>7}{'SCORE':>8}")
print("-"*90)
scored = []
for r in gated:
    s = score(r)
    scored.append((r, s))
    d_iq = (r['iq'] - iq_min) / (iq_max - iq_min) if r['iq'] is not None else 0.5
    d_c = (cmax - r['ce']) / (cmax - cmin)
    d_ps = (r['ps'] - ps_min) / (ps_max - ps_min)
    iq_s = f"{r['iq']:.2f}" if r['iq'] else "결측"
    print(f"{'':<4}{r['m']:<22}{iq_s:>7}{d_iq:>7.3f}{r['ce']:>8.4f}{d_c:>7.3f}{r['ps']:>7.3f}{d_ps:>7.3f}{s:>8.4f}")

scored.sort(key=lambda x: -x[1])
print("\n" + "="*112)
print("최종 순위 (abort 게이트 통과 모델만)")
print("="*112)
for i, (r, s) in enumerate(scored, 1):
    iq_note = "" if r['iq'] else "  ← 지능 점수 결측 (Manski 구간: " + f"{iq_min:.1f}~{iq_max:.1f}" + ")"
    print(f"  {i}. {r['m']:<22} SCORE={s:.4f}  IQ={r['iq'] if r['iq'] else '?'}{iq_note}")

print("\n" + "="*112)
print("왜 score/cost가 아니라 이 방법인가 — 수치 근거")
print("="*112)
print("""
1. score/cost = IQ / input_price는 캐시·output·성공률을 무시.
   예: deepseek-v4-flash raw score/cost = 51.77/0.14 = 370 (input만)
       하지만 실질 C_eff(캐시 99%) = $0.0248/1M → 실질 IQ/$ = 2087
       17배 차이. 캐시를 빼면 순위가 뒤집힌다.

2. abort는 순수 지능 문제가 아님 (quota/rate-limit가 대부분) — 그래서 '지능'으로
   벌점하지 않고 별도 하드 게이트로 다룬다. Kimi-K3는 IQ 59.70으로 1등이지만
   abort율 21% → 재시도+인적복구 비용 폭증 → 게이트 탈락.

3. 지능 결측 9개 모델은 점추정 대신 구간으로 보고 (Manski): 지능을 [51.77, 59.70]
   어디에 두든 이번 데이터로는 순위 확정 불가 → '순위 미정, 실행 데이터 수집 후 결정'.
""")

# ---------- Manski: 결측 모델이 상위권에 들어올 수 있는지 ----------
print("="*112)
print("Manski 경계 — 결측 모델 9개가 최고 지능(59.70) 가정해도 상위권 가능한가?")
print("="*112)
for r in [r for r in rows if not r['has_bench']]:
    # 비용만으로 가능한 최대 스코어 계산 (성공률·abort는 데이터 없음 → 미지)
    d_c = (cmax - r['ce']) / (cmax - cmin)
    d_iq_max = 1.0
    best_possible = (2*0.0 + 2*d_c + 1*1.0) / 5  # 성공률 0 가정 (가장 보수적) → 사실 실행데이터 없으면 0
    print(f"  {r['m']:<22} C_eff=${r['ce']:.4f}  → 비용만 보면 {'경쟁력 있음' if d_c > 0.5 else '비용 경쟁력 약함'}")
print("""
결론: 결측 9개 중 mimo-v2.5($0.0359), Qwen3.7-Flash($0.0156)는 비용이
flash에 근접하지만 실행 데이터(성공률·abort)가 없어 순위 확정 불가.
이들을 랭킹에 넣으려면 30~50회 실행 데이터를 먼저 모아야 한다.
""")
