"""P2-M5 acceptance test - verify all backend API endpoints.

Run while backend is running on http://127.0.0.1:8000.
All source is ASCII.
"""

import json
import urllib.request

BASE = "http://127.0.0.1:8000"
passed = 0
failed = 0


def api_get(path):
    with urllib.request.urlopen(f"{BASE}{path}", timeout=10) as r:
        return json.loads(r.read())


def test(name, condition, detail=""):
    global passed, failed
    if condition:
        passed += 1
        print(f"  [PASS] {name}")
    else:
        failed += 1
        print(f"  [FAIL] {name} {detail}")


print("=" * 60)
print("P2-M5 Acceptance Test - Backend API Verification")
print("=" * 60)

# 1. Health
print("\n[1] Health & Core")
r = api_get("/api/health")
test("health status ok", r.get("status") == "ok")

# 2. Projects
print("\n[2] Projects API")
r = api_get("/api/projects?limit=5")
test("projects list returns total", "total" in r, str(r)[:100])
test("projects list has items", "items" in r)

# 3. Plans
print("\n[3] Plans API")
r = api_get("/api/plans?limit=5")
test("plans list returns total", "total" in r)
test("plans list has items", "items" in r)

# 4. Experience CRUD
print("\n[4] Experience Library API")
r = api_get("/api/experience?limit=5")
test("experience list returns total", "total" in r)
test("experience list has items", "items" in r)

# Create a test case
print("  -- Create test case --")
test_data = {
    "topology": "SSSR",
    "source_plan_id": "ACCEPTANCE-TEST",
    "params": {"Airgap": 1.0, "RMSCurrent": 20},
    "metrics": {"tavg_nm": 2.5, "efficiency_pct": 85.0, "ripple_pct": 3.0},
    "conclusion": "Acceptance test case",
    "tags": ["acceptance-test"],
    "rating": 3
}
req = urllib.request.Request(
    f"{BASE}/api/experience",
    data=json.dumps(test_data).encode(),
    headers={"Content-Type": "application/json"},
    method="POST"
)
with urllib.request.urlopen(req, timeout=10) as r:
    created = json.loads(r.read())
test("create experience returns 201", created.get("id") is not None)
case_id = created.get("id")

# Get single case
r = api_get(f"/api/experience/{case_id}")
test("get single case", r.get("id") == case_id)
test("case has params", bool(r.get("params")))
test("case has metrics", bool(r.get("metrics")))

# Update case
print("  -- Update test case --")
update_data = {"conclusion": "Updated by acceptance test", "rating": 5, "tags": ["acceptance-test", "updated"]}
req = urllib.request.Request(
    f"{BASE}/api/experience/{case_id}",
    data=json.dumps(update_data).encode(),
    headers={"Content-Type": "application/json"},
    method="PUT"
)
with urllib.request.urlopen(req, timeout=10) as r:
    updated = json.loads(r.read())
test("update case returns updated", updated.get("conclusion") == "Updated by acceptance test")
test("update rating", updated.get("rating") == 5)

# Delete test case
print("  -- Delete test case --")
req = urllib.request.Request(
    f"{BASE}/api/experience/{case_id}",
    method="DELETE"
)
with urllib.request.urlopen(req, timeout=10) as r:
    test("delete case returns 204", r.status == 204)

# 5. Analytics
print("\n[5] Analytics API")
r = api_get("/api/analytics/metrics")
test("metrics list", len(r.get("metrics", [])) >= 10)

r = api_get("/api/analytics/experience/stats")
test("experience stats has total", "total" in r)
test("experience stats has topology_distribution", "topology_distribution" in r)
test("experience stats has metric_ranges", "metric_ranges" in r)

# Similar search
print("  -- Similar search --")
req = urllib.request.Request(
    f"{BASE}/api/analytics/experience/similar?top_k=3&tolerance=0.5",
    data=json.dumps({"params": {"Airgap": 1.0, "RMSCurrent": 20}}).encode(),
    headers={"Content-Type": "application/json"},
    method="POST"
)
with urllib.request.urlopen(req, timeout=10) as r:
    similar = json.loads(r.read())
test("similar search returns items", "items" in similar)

# 6. Scan parameters / Generation
print("\n[6] Generation / Rule Engine API")
r = api_get("/api/scan-parameters")
test("scan parameters list", len(r.get("parameters", [])) >= 5, str(r)[:100])

# 7. API docs
print("\n[7] API Documentation")
try:
    with urllib.request.urlopen(f"{BASE}/docs", timeout=5) as r:
        test("Swagger docs accessible", r.status == 200)
except Exception as e:
    test("Swagger docs accessible", False, str(e))

try:
    with urllib.request.urlopen(f"{BASE}/openapi.json", timeout=5) as r:
        spec = json.loads(r.read())
        test("OpenAPI spec has paths", len(spec.get("paths", {})) >= 10)
        test("OpenAPI spec paths count", len(spec.get("paths", {})) >= 15, f"count={len(spec.get('paths',{}))}")
except Exception as e:
    test("OpenAPI spec accessible", False, str(e))

# Summary
print("\n" + "=" * 60)
print(f"ACCEPTANCE TEST SUMMARY: {passed} passed, {failed} failed")
print("=" * 60)

if failed > 0:
    print("\nSome tests failed. Please review.")
    exit(1)
else:
    print("\nAll backend API acceptance tests passed!")
    exit(0)
