"""一言の依頼と材料つきの依頼を、同じモデルで比べる小実験。

使い方: --rescore は保存出力の再採点のみ。--run --output PATH は新規30回（利用枠を消費）。
採点は限定的な文字列検査で、意味や完成品質を保証しない。
"""

import argparse
import json
import re
import subprocess
import sys
import tempfile
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

HERE = Path(__file__).parent
MODELS = {"haiku": "claude-haiku-4-5-20251001", "sonnet": "claude-sonnet-5-5"}
N = 3

# ---- 依頼A: 出店者募集の告知文（材料を1段ずつ足す） ----
A_FACTS = """- イベント名: あおば町内会 秋のフリマ
- 日時: 2026年11月14日（土）10:00〜15:00
- 場所: あおば公園
- 出店者募集: 11月1日（日）まで。出店料500円
- 雨天: 11月15日（日）に順延
- 問い合わせ: 実行委員の森田（morita@aoba-furima.example）"""

A_L0 = "フリマの出店者募集の告知文を書いて。"
A_L1 = f"フリマの出店者募集の告知文を書いて。\n\n事実はこれだけ。ここにない情報は作らないで。\n{A_FACTS}"
A_L2 = f"""# 目的・読み手
町内会の掲示板アプリに投稿する。読むのは近所の住民で、出店してくれる人を増やしたい。

# 事実（これだけ。ここにない情報は作らない）
{A_FACTS}

# 制約
- 200字以内
- 絵文字・ハッシュタグは使わない
- 最初の1文で「出店者募集」と分かるようにする

# 依頼
出店者募集の告知文を書いてください。投稿文だけを出力してください。"""

# ---- 依頼B: 取引先メールへの返信 ----
MAIL = """件名: 打ち合わせ日程のご相談

田中様

お世話になっております。株式会社ミドリ工房の山本です。
新商品の販促物について、一度お打ち合わせをお願いできればと思います。
10月中旬でご都合のよい日時を教えていただけますでしょうか。

山本"""
B_L0 = f"次のメールに返信して。\n\n{MAIL}"
B_L2 = f"""<受信メール>
{MAIL}
</受信メール>

<使ってよい事実>
- 私は田中。株式会社ミドリ工房の山本様宛てに返信する
- 空いているのは10月14日（水）14:00〜17:00と、10月16日（金）終日。15日は不可
- 方法はオンライン（Google Meet）。リンクは前日までに送る
- 打ち合わせ用の資料は、私が前日までにメールで送る
</使ってよい事実>

<制約>
- 300字以内、件名つき
- ここにない約束や事実は書かない
</制約>

<依頼>
山本様への返信メールを書いてください。本文だけを出力してください。
</依頼>"""

TASKS = {
    "A0_一言": A_L0,
    "A1_事実だけ": A_L1,
    "A2_事実+目的+制約": A_L2,
    "B0_一言": B_L0,
    "B2_材料つき": B_L2,
}

INVENTED = ["先着", "抽選", "無料", "駐車場", "限定", "定員", "テント", "テーブル", "不用品", "手作り", "ハンドメイド", "ブース"]


def nospace_len(s):
    return len(re.sub(r"\s", "", s))


def has_placeholder(s):
    return bool(re.search(r"【[^】]*】|\[[^\]]*\]|［[^］]*］|○○|〇〇|XX", s.replace("【出店者募集】", "")))


def score(task, out):
    c = {"穴あきでない（【】・[ ]・○○なし）": not has_placeholder(out)}
    if task.startswith("A"):
        c["11/14・あおば公園を入れた"] = bool(re.search(r"11月14日|11/14", out)) and "あおば公園" in out
        c["締切11/1と出店料500円を入れた"] = bool(re.search(r"11月1日|11/1(?!\d)", out)) and "500円" in out
        c["雨天順延を入れた"] = "順延" in out
        c["連絡先アドレスが正確"] = "morita@aoba-furima.example" in out
        c["与えていない条件を足していない"] = not any(w in out for w in INVENTED)
        c["200字以内"] = nospace_len(out) <= 200
    else:
        c["空き時間が事実どおり（14日14〜17時・16日終日）"] = bool(re.search(r"10月14日[^\n]*14:00[〜～~-]17:00", out)) and bool(re.search(r"10月16日[^\n]*終日", out))
        c["不可の10/15を候補にしていない"] = not re.search(r"^[・\-\s]*10月15日", out, re.M)
        c["オンライン(Meet)・前日リンクに触れた"] = "Meet" in out and "前日" in out
        c["資料を前日までに送ると書いた"] = bool(re.search(r"資料[^\n]*前日|前日[^\n]*資料", out))
        c["300字以内"] = nospace_len(out) <= 300
    return c


def run_one(args):
    task, model_key, i = args
    with tempfile.TemporaryDirectory() as wd:
        cmd = [
            "claude", "-p", TASKS[task], "--model", MODELS[model_key],
            "--tools", "", "--setting-sources", "", "--disable-slash-commands",
            "--strict-mcp-config", "--system-prompt", "You are a helpful assistant.",
            "--no-session-persistence", "--output-format", "json",
        ]
        r = subprocess.run(cmd, cwd=wd, capture_output=True, text=True, timeout=300, stdin=subprocess.DEVNULL)
    d = json.loads(r.stdout)
    out = d["result"]
    return {
        "task": task, "model": model_key, "model_id": MODELS[model_key], "run": i,
        "prompt": TASKS[task], "output": out, "chars": nospace_len(out),
        "checks": score(task, out), "cost_usd": d.get("total_cost_usd"),
    }


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    mode = parser.add_mutually_exclusive_group(required=True)
    mode.add_argument("--rescore", action="store_true")
    mode.add_argument("--run", action="store_true")
    parser.add_argument("--output", type=Path, help="新規生成の保存先。既存ファイルは上書きしない")
    args = parser.parse_args()
    if args.rescore:
        rows = [json.loads(line) for line in open(HERE / "results.jsonl")]
        for r in rows:
            r["checks"] = score(r["task"], r["output"])
        with open(HERE / "results.jsonl", "w") as f:
            for r in rows:
                f.write(json.dumps(r, ensure_ascii=False) + "\n")
        sys.exit()
    if args.output is None:
        parser.error("--run には --output が必要です")
    jobs = [(t, m, i) for t in TASKS for m in MODELS for i in range(N)]
    with args.output.open("x") as f, ThreadPoolExecutor(6) as ex:
        for res in ex.map(run_one, jobs):
            f.write(json.dumps(res, ensure_ascii=False) + "\n")
            f.flush()
            print(res["task"], res["model"], res["run"], res["chars"], file=sys.stderr)
