"""条件名を伏せて、同じお題・同じ回の8本を判定役に読ませる。判定役は Claude と Codex(GPT) の2系統。"""
import concurrent.futures as cf, json, pathlib, random, re, subprocess, sys, tempfile
from materials import *

N = 8; ORDER = ["base", "noguard", "P", "N", "S", "A", "F", "ALL", "F2", "ALL2"]
OUT = pathlib.Path("judge"); OUT.mkdir(exist_ok=True)

def prompt(task, i):
    rng = random.Random(f"{task}-{i}"); order = ORDER[:]; rng.shuffle(order)
    cands = "\n\n".join(f"## 候補{k+1}\n{pathlib.Path(f'runs/{c}_{task}_{i}.txt').read_text()}" for k, c in enumerate(order))
    return order, f"""あなたは、町の自転車屋の店主本人の代わりに、AIが書いたX投稿の「本人らしさ」を点検する編集者です。

# 本人について（事実の根拠）
{CORE}

{NOTES}

# 本人が過去に書いた投稿
{SAMPLES}

# 本人が言わないと決めている表現
{AVOID}

# 今回のお題
{TASKS[task][1]}
同じお題で本人が実際に書いた投稿（参考）：
「{TRUTH[task]}」

# 候補（10本）
{cands}

# 依頼
候補ごとに次を判定してください。候補に説明文や空欄（【】や[ ]）が含まれていて、そのままXに出せない場合は verdict を "不可" にします。
- verdict："そのまま出せる" / "小修正で出せる" / "論点から違う" / "不可" のいずれか。本人が「これは自分が言う」と思えるかで判断する。
- unsupported：上の「事実の根拠」（本人についての事実のブロックを含む）に無い事実・体験・数字・主張の短い引用のリスト。なければ空配列。
- rank：本人らしい順に候補番号を並べた配列（10個。1位が先頭）。
JSONだけを出力してください。形式：{{"verdicts":{{"1":"…","2":"…"}},"unsupported":{{"1":[],"2":[]}},"rank":[3,1,…]}}"""

def run_claude(p):
    with tempfile.TemporaryDirectory() as d:
        r = subprocess.run(["claude","-p","--tools","","--no-session-persistence","--disable-slash-commands","--output-format","json"],
                           input=p, capture_output=True, text=True, cwd=d, timeout=900)
    return json.loads(r.stdout)["result"]

def run_codex(p):
    with tempfile.TemporaryDirectory() as d:
        o = pathlib.Path(d)/"o.txt"
        subprocess.run(["codex","exec","--skip-git-repo-check","-s","read-only","-C",d,"-o",str(o),p],
                       stdin=subprocess.DEVNULL, capture_output=True, text=True, timeout=900)
        return o.read_text()

def parse(t):
    m = re.search(r"\{.*\}", t, re.S); return json.loads(m.group(0))

def one(who, task, i):
    f = OUT/f"{who}_{task}_{i}.json"
    if f.exists(): return
    order, p = prompt(task, i)
    for _ in range(3):
        try:
            j = parse((run_claude if who=="claude" else run_codex)(p)); break
        except Exception as e: j = None
    if j is None: print("FAIL", who, task, i); return
    j["order"] = order; f.write_text(json.dumps(j, ensure_ascii=False, indent=1))

if __name__ == "__main__":
    whos = sys.argv[1:] or ["claude","codex"]
    jobs = [(w,t,i) for w in whos for t in TASKS for i in range(N)]
    with cf.ThreadPoolExecutor(6) as ex:
        for f in [ex.submit(one,*j) for j in jobs]: f.result()
