from __future__ import annotations

import argparse
import datetime as dt
import json
import sys
import time
import urllib.error
import urllib.request
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_REPORT = ROOT / "reports" / "inference-endpoint-check.json"


def fetch_models(base_url: str, timeout: int) -> tuple[list[str], int]:
    started_at = time.perf_counter()
    request = urllib.request.Request(f"{base_url.rstrip('/')}/v1/models", method="GET")
    with urllib.request.urlopen(request, timeout=timeout) as response:
        payload = json.loads(response.read().decode("utf-8"))
    latency_ms = round((time.perf_counter() - started_at) * 1000)
    rows = payload.get("data") if isinstance(payload, dict) else []
    if not isinstance(rows, list):
        return [], latency_ms
    return [str(row.get("id")) for row in rows if isinstance(row, dict) and row.get("id")], latency_ms


def check_endpoint(base_url: str, expected_model: str | None, timeout: int) -> dict:
    result = {
        "base_url": base_url,
        "expected_model": expected_model,
        "status": "failed",
        "models": [],
        "available": None,
        "latency_ms": None,
        "error": None,
    }
    try:
        models, latency_ms = fetch_models(base_url, timeout)
    except (TimeoutError, OSError, urllib.error.URLError, ValueError) as exc:
        result["error"] = str(exc)
        return result

    result["models"] = models
    result["latency_ms"] = latency_ms
    result["available"] = expected_model in models if expected_model else None
    result["status"] = "ok" if models and (expected_model is None or result["available"]) else "failed"
    return result


def main() -> int:
    parser = argparse.ArgumentParser(description="Check an OpenAI-compatible inference endpoint.")
    parser.add_argument("--base-url", default="http://docker-gpu.cin.su:8000")
    parser.add_argument("--expected-model")
    parser.add_argument("--timeout", type=int, default=10)
    parser.add_argument("--report", type=Path, default=DEFAULT_REPORT)
    parser.add_argument("--print", action="store_true")
    parser.add_argument("--no-report", action="store_true")
    args = parser.parse_args()

    result = check_endpoint(args.base_url, args.expected_model, args.timeout)
    report = {
        "created_at": dt.datetime.now(dt.UTC).isoformat(),
        "status": result["status"],
        "checks": [result],
    }

    if not args.no_report:
        args.report.parent.mkdir(parents=True, exist_ok=True)
        args.report.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")

    if args.print:
        print(json.dumps(report, ensure_ascii=False, indent=2))
    else:
        print(f"Endpoint status: {result['status']} ({args.base_url})")
        if result["error"]:
            print(result["error"], file=sys.stderr)

    return 0 if result["status"] == "ok" else 1


if __name__ == "__main__":
    raise SystemExit(main())
