#!/usr/bin/env python3
"""정정 반영 fresh E2E — 53스텝(텍스트 39+floor_plan_render+FPDEP 13) 순차 실행.

e2e_v16_seq_runner.py 복제 (STATE/STEPS 파일명만 변경, 커밋 금지).
목록=e2e_v16corr_steps.json (step_manifest order 정렬, category run-all 미사용).
usage: backend/.venv/bin/python e2e_v16corr_runner.py
"""
import json
import sys
import time
from pathlib import Path

import requests

BASE = "http://localhost:8000"
ROOT = Path("/Users/manta/Documents/Projects/TheRoad-I1")
STATE = json.loads((ROOT / "scratchpad" / "e2e_v16corr_state.json").read_text())
PID, EID = STATE["project_id"], STATE["episode_id"]
STEPS = json.loads(
    (ROOT / "scratchpad" / "e2e_v16corr_steps.json").read_text())["runnable"]

TERMINAL_OK = {"completed", "skipped", "not_applicable"}
TERMINAL_BAD = {"failed"}

s = requests.Session()


def login():
    r = s.post(f"{BASE}/api/v1/auth/login",
               json={"username": "admin", "password": "admin123"}, timeout=30)
    r.raise_for_status()


def status_map():
    r = s.get(f"{BASE}/api/v1/projects/{PID}/episodes/{EID}/steps", timeout=60)
    r.raise_for_status()
    return {x["step_id"]: x for x in r.json()["steps"]}


def run_step(sid):
    t0 = time.time()
    st = status_map().get(sid) or {}
    if st.get("status") in TERMINAL_OK:
        print(f"[{sid}] already {st.get('status')}", flush=True)
        return True
    r = s.post(f"{BASE}/api/v1/projects/{PID}/episodes/{EID}/steps/{sid}",
               params={"mode": "resume"}, timeout=120)
    if r.status_code != 200:
        print(f"[{sid}] start FAILED http={r.status_code} {r.text[:300]}",
              flush=True)
        return False
    print(f"[{sid}] started", flush=True)
    while True:
        time.sleep(30)
        try:
            st = status_map().get(sid) or {}
        except Exception as exc:
            print(f"[{sid}] poll error {exc}", flush=True)
            continue
        cur = st.get("status")
        if cur in TERMINAL_OK:
            print(f"[{sid}] {cur} ({int(time.time()-t0)}s)", flush=True)
            return True
        if cur in TERMINAL_BAD:
            print(f"[{sid}] FAILED ({int(time.time()-t0)}s) — "
                  f"{json.dumps(st, ensure_ascii=False)[:400]}", flush=True)
            return False
        if time.time() - t0 > 5400:
            print(f"[{sid}] TIMEOUT 90min (status={cur})", flush=True)
            return False


def main():
    login()
    print(f"target {len(STEPS)} steps | pid={PID} eid={EID}", flush=True)
    for sid in STEPS:
        if not run_step(sid):
            print(f"STOP at {sid}", flush=True)
            sys.exit(1)
    print("ALL STEPS DONE", flush=True)


if __name__ == "__main__":
    main()
