"""Connector API: install, test, tool discovery, secret safety, RBAC, tenancy."""

from __future__ import annotations

import httpx
from legate.policy.roles import Role

SECRET = "xoxb-super-secret-token"


def _slack_handler(request: httpx.Request) -> httpx.Response:
    if request.url.path.endswith("/auth.test"):
        return httpx.Response(200, json={"ok": True, "user": "legate-bot"})
    return httpx.Response(404, json={"ok": False, "error": "unknown"})


def test_install_lists_and_never_returns_secrets(client, helpers):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]

    created = helpers.install_connector(
        client, token, type="slack", name="Team Slack", secrets={"bot_token": SECRET}
    )
    assert created["type"] == "slack"
    assert "secrets" not in created and "bot_token" not in str(created)

    listed = client.get("/connectors", headers=helpers.headers(token))
    assert SECRET not in listed.text  # secret never leaves the server

    got = client.get(f"/connectors/{created['id']}", headers=helpers.headers(token))
    assert got.status_code == 200 and SECRET not in got.text


def test_install_validates_type_and_secrets(client, helpers):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]

    bad_type = client.post(
        "/connectors", json={"type": "nope", "name": "x"}, headers=helpers.headers(token)
    )
    assert bad_type.status_code == 422

    missing_secret = client.post(
        "/connectors",
        json={"type": "slack", "name": "x", "secrets": {}},
        headers=helpers.headers(token),
    )
    assert missing_secret.status_code == 422


def test_connector_tools_and_types(client, helpers):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]
    conn = helpers.install_connector(client, token, type="slack", secrets={"bot_token": SECRET})

    tools = client.get(f"/connectors/{conn['id']}/tools", headers=helpers.headers(token))
    assert {t["name"] for t in tools.json()} >= {"slack.post_message", "slack.list_channels"}

    types = client.get("/connector-types", headers=helpers.headers(token))
    assert {t["type"] for t in types.json()} >= {"slack", "http", "email"}


def test_test_connection_updates_status(client, helpers, set_connector_http):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]
    conn = helpers.install_connector(client, token, type="slack", secrets={"bot_token": SECRET})
    assert conn["status"] == "untested"

    set_connector_http(_slack_handler)
    result = client.post(f"/connectors/{conn['id']}/test", headers=helpers.headers(token))
    assert result.status_code == 200
    body = result.json()
    assert body["ok"] is True and body["status"] == "ok"

    refreshed = client.get(f"/connectors/{conn['id']}", headers=helpers.headers(token)).json()
    assert refreshed["status"] == "ok"


def test_update_and_delete_connector(client, helpers):
    owner = helpers.bootstrap_owner(client)
    token = owner["access_token"]
    conn = helpers.install_connector(client, token, type="slack", secrets={"bot_token": SECRET})

    patched = client.patch(
        f"/connectors/{conn['id']}",
        json={"name": "Renamed", "secrets": {"bot_token": "xoxb-new"}},
        headers=helpers.headers(token),
    )
    assert patched.status_code == 200 and patched.json()["name"] == "Renamed"

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


def test_rbac_builder_can_operator_cannot(client, helpers):
    owner = helpers.bootstrap_owner(client)
    builder = helpers.add_member(client, owner["access_token"], email="b@x.com", role=Role.BUILDER)
    operator = helpers.add_member(
        client, owner["access_token"], email="o@x.com", role=Role.OPERATOR
    )

    helpers.install_connector(
        client, builder["access_token"], type="slack", secrets={"bot_token": SECRET}
    )

    forbidden = client.post(
        "/connectors",
        json={"type": "slack", "name": "x", "secrets": {"bot_token": SECRET}},
        headers=helpers.headers(operator["access_token"]),
    )
    assert forbidden.status_code == 403


def test_connectors_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")
    conn = helpers.install_connector(
        client, a["access_token"], type="slack", secrets={"bot_token": SECRET}
    )

    assert (
        client.get(
            f"/connectors/{conn['id']}", headers=helpers.headers(b["access_token"])
        ).status_code
        == 404
    )
    assert client.get("/connectors", headers=helpers.headers(b["access_token"])).json() == []
