"""E2E batch upload test: upload 10 CSV files (2 batches of 5), cluster, verify."""
import subprocess, time, os, sys, glob, json

PROJ = r"E:\hjq\天璇"
PORT = 8765
BASE = f"http://127.0.0.1:{PORT}"

# ═══ Kill old server on PORT ═══
print("1. Killing old server on port 8765...")
kill_result = subprocess.run(
    f'Get-NetTCPConnection -LocalPort {PORT} -ErrorAction SilentlyContinue | '
    f'ForEach-Object {{ taskkill /F /PID $_.OwningProcess }}',
    shell=True, capture_output=True, text=True
)
time.sleep(2)

# ═══ Start server ═══
print("2. Starting Django server...")
os.chdir(PROJ)
server = subprocess.Popen(
    [r"runtime\python\python.exe", "manage.py", "runserver", f"127.0.0.1:{PORT}", "--noreload"],
    stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
time.sleep(6)
print("   Server started.")

import requests

# ═══ Upload 10 files (single batch — batch endpoint has table-race pre-existing bug) ═══
print("3. Uploading 10 CSV files...")
csvs = sorted(glob.glob(os.path.join(PROJ, "data", "multi_upload", "*.csv")))[:10]
files = [("files", (os.path.basename(f), open(f, "rb"), "text/csv")) for f in csvs]
r = requests.post(f"{BASE}/upload/csv/", files=files, timeout=120)
data = r.json()
if "error" in data:
    print(f"   UPLOAD FAILED: {data['error']}")
    server.terminate()
    sys.exit(1)
run_id = data["run_id"]
print(f"   Upload OK → run_id={run_id}")

# ═══ Poll until ready ═══
print("4. Polling status until ready...")
status = {}
for i in range(180):
    try:
        r = requests.get(f"{BASE}/runs/{run_id}/status/", timeout=30)
        status = r.json()
    except requests.exceptions.Timeout:
        print(f"   Poll #{i+1} timed out, retrying...")
        time.sleep(3)
        continue
    except requests.exceptions.ConnectionError:
        print(f"   Poll #{i+1} connection refused, server may have crashed")
        time.sleep(5)
        continue
    s = status.get("status")
    if s in ("ready", "failed"):
        break
    if i % 15 == 0 and i > 0:
        print(f"   Still loading... status={s}")
    time.sleep(3)

print(f"   Status={status.get('status')}, flows={status.get('total_flows')}, "
      f"error={status.get('error_message','')[:200]}")

if status.get("status") == "failed":
    print(f"   FAILED: {status.get('error_message','')}")
    server.terminate()
    sys.exit(1)

# ═══ Run clustering ═══
print("5. Running clustering (HDBSCAN)...")
r = requests.post(f"{BASE}/analyze/run/",
    json={"run_id": run_id, "algorithm": "hdbscan", "min_cluster_size": 5, "cluster_mode": "raw"},
    timeout=30)
print(f"   Cluster trigger: {r.json()}")

for i in range(180):
    try:
        r = requests.get(f"{BASE}/runs/{run_id}/status/", timeout=30)
        status = r.json()
    except requests.exceptions.Timeout:
        print(f"   Poll #{i+1} timed out after 30s, retrying...")
        time.sleep(2)
        continue
    except requests.exceptions.ConnectionError:
        print(f"   Poll #{i+1} connection refused, server may have crashed")
        time.sleep(5)
        continue
    s = status.get("status")
    if s in ("completed", "failed"):
        break
    if i % 20 == 0 and i > 0:
        print(f"   Still clustering... status={s}")
    time.sleep(5)

print(f"   entity_count={status.get('entity_count')}, "
      f"cluster_count={status.get('cluster_count')}, "
      f"status={status.get('status')}")

# ═══ Cleanup & verdict ═══
server.terminate()
server.wait()

if status.get("status") == "completed" and status.get("cluster_count", 0) > 0:
    print("E2E PASSED")
    sys.exit(0)
else:
    print(f"E2E FAILED (status={status.get('status')}, clusters={status.get('cluster_count')})")
    sys.exit(1)
