"""Agent CRUD, tool listing, RBAC, and tenant isolation."""

from __future__ import annotations

from legate.policy.roles import Role


def test_builder_can_create_agent_viewer_cannot(client, helpers):
    owner = helpers.bootstrap_owner(client, email="owner@x.com")
    builder = helpers.add_member(client, owner["access_token"], email="b@x.com", role=Role.BUILDER)
    viewer = helpers.add_member(client, owner["access_token"], email="v@x.com", role=Role.VIEWER)

    created = client.post(
        "/agents",
        json={"name": "Support", "model": "fake-model", "tools": ["kb.search"]},
        headers=helpers.headers(builder["access_token"]),
    )
    assert created.status_code == 201, created.text
    assert created.json()["tools"] == ["kb.search"]

    forbidden = client.post(
        "/agents",
        json={"name": "Nope", "model": "fake-model"},
        headers=helpers.headers(viewer["access_token"]),
    )
    assert forbidden.status_code == 403


def test_create_agent_rejects_unknown_tool(client, helpers):
    owner = helpers.bootstrap_owner(client)
    resp = client.post(
        "/agents",
        json={"name": "Bad", "model": "m", "tools": ["does.not.exist"]},
        headers=helpers.headers(owner["access_token"]),
    )
    assert resp.status_code == 422
    assert "does.not.exist" in resp.text


def test_list_tools_returns_builtins(client, helpers):
    owner = helpers.bootstrap_owner(client)
    resp = client.get("/tools", headers=helpers.headers(owner["access_token"]))
    assert resp.status_code == 200
    names = {t["name"] for t in resp.json()}
    assert {"kb.search", "http.request"} <= names


def test_get_update_delete_agent(client, helpers):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]
    agent = helpers.create_agent(client, token, name="Orig")

    got = client.get(f"/agents/{agent['id']}", headers=helpers.headers(token))
    assert got.status_code == 200 and got.json()["name"] == "Orig"

    patched = client.patch(
        f"/agents/{agent['id']}",
        json={"name": "Renamed", "tools": ["http.request"]},
        headers=helpers.headers(token),
    )
    assert patched.status_code == 200
    assert patched.json()["name"] == "Renamed"
    assert patched.json()["tools"] == ["http.request"]

    deleted = client.delete(f"/agents/{agent['id']}", headers=helpers.headers(token))
    assert deleted.status_code == 204
    assert client.get(f"/agents/{agent['id']}", headers=helpers.headers(token)).status_code == 404


def test_agents_are_tenant_scoped(client, helpers):
    a = helpers.bootstrap_owner(client, email="a@x.com", name="A")
    b = helpers.bootstrap_owner(client, email="b@x.com", name="B")
    agent = helpers.create_agent(client, a["access_token"], name="Secret")

    # B cannot see A's agent.
    assert (
        client.get(f"/agents/{agent['id']}", headers=helpers.headers(b["access_token"])).status_code
        == 404
    )
    listed = client.get("/agents", headers=helpers.headers(b["access_token"]))
    assert listed.json() == []


def test_agent_create_is_audited(client, helpers):
    owner = helpers.bootstrap_owner(client)
    helpers.create_agent(client, owner["access_token"], name="Audited")
    audit = client.get("/audit", headers=helpers.headers(owner["access_token"]))
    actions = [e["action"] for e in audit.json()]
    assert "agent.create" in actions
