"""Run, pack and replay the launch-campaign study.

    # live: asks the model (DeepSeek from .env); 2,128 to 3,742 model calls per seed in the published runs
    .venv/bin/python research/studies/market-perception/press-brain-ltv/run.py live --seeds 101 102 103 104 105
    # replay: no model, no network; every round's state hash must match the evidence
    .venv/bin/python research/studies/market-perception/press-brain-ltv/run.py replay --seeds 101
    # then
    .venv/bin/python research/studies/market-perception/press-brain-ltv/analyze.py

A live run writes ``target/press-brain-ltv/seed-<n>/`` with scripts/society/experiment.py
(seven arms in threads) and packs what replay and analysis need into
``evidence/seed-<n>/``: ``summary.json``, ``journal.jsonl.gz`` (every model response,
keyed by prompt) and ``trace-<arm>.jsonl.gz``. A replay unpacks the journal, reruns the
experiment offline (a journal miss is an error) and compares every round's state hash,
outcome and decision count with the evidence summary.

A live run with no ``DEEPSEEK_API_KEY`` stops before starting; it never substitutes
anything for a model response.
"""

import argparse
import gzip
import os
import pathlib
import shutil
import subprocess
import sys

HERE = pathlib.Path(__file__).resolve().parent
ROOT = HERE.parents[3]
SPEC = HERE / "spec/launch-campaign.json"
EVIDENCE = HERE / "evidence"
TARGET = ROOT / "target/press-brain-ltv"
EXPERIMENT = ROOT / "scripts/society/experiment.py"


def has_key():
    if os.environ.get("DEEPSEEK_API_KEY"):
        return True
    env = ROOT / ".env"
    return env.exists() and any(line.split("=", 1)[0].strip() == "DEEPSEEK_API_KEY" and line.split("=", 1)[1].strip()
                                for line in env.read_text().splitlines() if "=" in line)


def pack(run, seed):
    dest = EVIDENCE / f"seed-{seed}"
    dest.mkdir(parents=True, exist_ok=True)
    shutil.copy(run / "summary.json", dest / "summary.json")
    for path in sorted(run.glob("trace-*.jsonl")) + [run / "journal.jsonl"]:
        with open(path, "rb") as src, gzip.GzipFile(dest / (path.name + ".gz"), "wb", mtime=0) as out:
            shutil.copyfileobj(src, out)
    return dest


def main(argv=None):
    parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument("mode", choices=["live", "replay", "pack"])
    parser.add_argument("--seeds", type=int, nargs="+", default=[101, 102, 103, 104, 105])
    parser.add_argument("--runs", default=str(TARGET), help="where runs are written (pack reads from here)")
    args = parser.parse_args(argv)
    runs = pathlib.Path(args.runs)
    if args.mode == "live" and not has_key():
        print("error: no DEEPSEEK_API_KEY in the environment or .env. A live run needs the model; "
              "to reproduce the published results without it, use `run.py replay`.", file=sys.stderr)
        return 2
    failed = False
    for seed in args.seeds:
        run = runs / f"seed-{seed}"
        if args.mode == "live":
            code = subprocess.call([sys.executable, str(EXPERIMENT), str(SPEC), "--out", str(run), "--seed", str(seed),
                                    "--parallel"])
            if code:
                return code
            print(f"packed {pack(run, seed)}")
        elif args.mode == "pack":
            print(f"packed {pack(run, seed)}")
        else:
            evidence = EVIDENCE / f"seed-{seed}"
            run = TARGET / f"replay-{seed}"
            run.mkdir(parents=True, exist_ok=True)
            journal = run / "journal.replay.jsonl"
            with gzip.open(evidence / "journal.jsonl.gz", "rb") as src, open(journal, "wb") as out:
                shutil.copyfileobj(src, out)
            result = subprocess.run([sys.executable, str(EXPERIMENT), str(SPEC), "--out", str(run), "--seed", str(seed),
                                     "--offline", "--journal", str(journal), "--expect", str(evidence / "summary.json")],
                                    capture_output=True, text=True)
            # experiment.py also exits 1 when its common-random-numbers check flags a pair;
            # in these runs every flag is a post renumbered across arms (see analyze.py), so
            # the replay verdict is its own line.
            verdict = next((line for line in result.stdout.splitlines() if line.startswith("replay:")), "replay: no verdict")
            print(f"seed {seed}: {verdict}")
            if result.stderr.strip():
                print(result.stderr.strip()[-2000:], file=sys.stderr)
            failed = failed or verdict != "replay: identical"
    return 1 if failed else 0


if __name__ == "__main__":
    sys.exit(main())
