from __future__ import annotations

import sys
import types

import pytest


def test_ray_serve_client_calls_start_run_status(monkeypatch):
    import ray  # provided by conftest stub

    calls: list[tuple[str, object]] = []

    def _init(*args, **kwargs):
        calls.append(("ray.init", {"args": args, "kwargs": kwargs}))

    monkeypatch.setattr(ray, "init", _init, raising=False)

    serve = types.ModuleType("ray.serve")

    def _start(**kwargs):
        calls.append(("serve.start", kwargs))
        return None

    def _run(app, name=None, route_prefix=None):
        calls.append(("serve.run", {"app": app, "name": name, "route_prefix": route_prefix}))
        return {"deployed": True}

    def _status():
        calls.append(("serve.status", None))
        return {"ok": True}

    def _delete(name: str):
        calls.append(("serve.delete", {"name": name}))
        return {"deleted": True}

    serve.start = _start  # type: ignore[attr-defined]
    serve.run = _run  # type: ignore[attr-defined]
    serve.status = _status  # type: ignore[attr-defined]
    serve.delete = _delete  # type: ignore[attr-defined]

    sys.modules["ray.serve"] = serve
    ray.serve = serve  # type: ignore[attr-defined]

    from argus.service.serve_client import RayServeClient

    client = RayServeClient(http_port=8000, proxy_location="HeadOnly", ray_init_address="auto")
    client.ensure_started()
    out = client.apply_app(app="APP", app_name="argus_llm_app", route_prefix="/")
    st = client.get_status()
    deleted = client.delete_app(app_name="mk1")

    assert out == {"deployed": True}
    assert st == {"ok": True}
    assert deleted == {"deleted": True}

    # Verify call order and key args.
    assert calls[0][0] == "ray.init"
    assert calls[0][1]["kwargs"].get("ignore_reinit_error") is True
    assert calls[1][0] == "serve.start"
    assert calls[1][1]["http_options"]["port"] == 8000
    assert calls[2][0] == "serve.run"
    assert calls[2][1]["name"] == "argus_llm_app"
    assert calls[3][0] == "serve.status"
    assert calls[4][0] == "serve.delete"


def test_ray_serve_client_rejects_dict_app(monkeypatch):
    import ray  # provided by conftest stub

    def _init(*args, **kwargs):
        return None

    monkeypatch.setattr(ray, "init", _init, raising=False)

    from argus.service.serve_client import RayServeClient

    client = RayServeClient(http_port=8000, proxy_location="HeadOnly", ray_init_address="auto")
    with pytest.raises(ValueError, match="invalid serve app object"):
        client.apply_app(app={"llm_configs": []}, app_name="mk1", route_prefix="/serve/mk1")
