"""Run the negative flow test with faulthandler enabled to capture native stack at crash."""
import os
import sys
import time
import json
import requests
import subprocess
from pathlib import Path

ROOT = Path(os.getcwd())
TS = time.strftime("%Y%m%d_%H%M%S")

SLOPPY = ROOT / "sloppy.py"
env = os.environ.copy()
env["PYTHONPATH"] = str(ROOT.absolute())
env["PYTHONFAULTHANDLER"] = "1"
env["PYTHONFAULTHANDLER_FILES"] = str(ROOT / "logs" / f"sloppy_faulthandler_{TS}.log")
log_path = ROOT / "logs" / f"sloppy_diag4_{TS}.log"
log_path.parent.mkdir(exist_ok=True)
log_file = open(log_path, "w", encoding="utf-8")

print(f"Spawning {SLOPPY} with faulthandler...")
proc = subprocess.Popen(
    ["uv", "run", "python", "-u", "-X", "faulthandler", str(SLOPPY), "--enable-test-hooks"],
    stdout=log_file,
    stderr=log_file,
    text=True,
    cwd=str(ROOT.absolute()),
    env=env,
)
print(f"  PID: {proc.pid}")
print(f"  faulthandler log: {env['PYTHONFAULTHANDLER_FILES']}")

print("Waiting for hook server...")
ready = False
start = time.time()
while time.time() - start < 30:
    try:
        r = requests.get("http://127.0.0.1:8999/status", timeout=0.5)
        if r.status_code == 200:
            ready = True
            break
    except: pass
    if proc.poll() is not None:
        print(f"  proc died rc={proc.returncode}")
        break
    time.sleep(0.5)

if not ready:
    print("FAILED to start")
    log_file.close()
    sys.exit(1)

def post(label, payload):
    print(f"POST {label}")
    r = requests.post("http://127.0.0.1:8999/api/gui", json=payload, timeout=5)
    return r

mock_path = (ROOT / "tests" / "mock_gemini_cli.py").absolute()
post("reset", {"action": "click", "item": "btn_reset"})
time.sleep(0.5)
post("provider", {"action": "set_value", "item": "current_provider", "value": "gemini_cli"})
time.sleep(0.5)
post("gcli_path", {"action": "set_value", "item": "gcli_path", "value": f'"{sys.executable}" "{mock_path}"'})
time.sleep(0.5)
post("env", {"action": "custom_callback", "callback": "_set_env_var", "args": ["MOCK_MODE", "malformed_json"]})
time.sleep(0.5)
post("input", {"action": "set_value", "item": "ai_input", "value": "Trigger"})
time.sleep(0.5)
print("CLICK btn_gen_send")
post("gen", {"action": "click", "item": "btn_gen_send"})
time.sleep(5)
print(f"  poll={proc.poll()}")

if proc.poll() is None:
    proc.terminate()
    try: proc.wait(timeout=5)
    except: proc.kill()
log_file.close()

# Read faulthandler output
fh_path = Path(env["PYTHONFAULTHANDLER_FILES"])
if fh_path.exists():
    print(f"\n=== faulthandler log ===")
    with open(fh_path, encoding="utf-8") as f:
        print(f.read())
