"""Tests for fastapi-gsap broker."""
import pytest
from httpx import AsyncClient

@pytest.mark.asyncio
async def test_health(client: AsyncClient):
    resp = await client.get("/health/")
    assert resp.status_code == 200
    assert resp.json()["gsap_version"] == "0.1.0"

@pytest.mark.asyncio
async def test_list_drivers(client: AsyncClient):
    resp = await client.get("/governance/drivers/")
    assert resp.status_code == 200
    assert "keycloak" in resp.json()["drivers"]

@pytest.mark.asyncio
async def test_authorize_bad_driver(client: AsyncClient):
    resp = await client.post("/governance/authorize/", json={
        "playbook": "test", "corpus_entry_cid": "sha256:a", "parameters_cid": "sha256:b",
        "accord_template": "test", "driver_id": "nonexistent"})
    assert resp.status_code == 400

@pytest.mark.asyncio
async def test_authorize_no_token(client: AsyncClient):
    resp = await client.post("/governance/authorize/", json={
        "playbook": "test", "corpus_entry_cid": "sha256:a", "parameters_cid": "sha256:b",
        "accord_template": "test", "driver_id": "keycloak"})
    assert resp.status_code == 403

@pytest.mark.asyncio
async def test_full_ac_cr_cycle(client: AsyncClient, mocker):
    from gsap_broker.drivers.base import AuthResult
    mocker.patch("gsap_broker.drivers.keycloak.KeycloakDriver.authenticate",
                 return_value=AuthResult(status=AuthResult.STATUS_AUTHORIZED,
                                         principal_did="did:web:test/p/sam", token_jti="jti-1", mfa_satisfied=True))

    auth_resp = await client.post("/governance/authorize/", json={
        "playbook": "test-echo", "corpus_entry_cid": "sha256:" + "a"*64,
        "parameters_cid": "sha256:" + "b"*64, "accord_template": "test-ops", "driver_id": "keycloak"})
    assert auth_resp.status_code == 200
    ctx_id = auth_resp.json()["authorization_context"]["context_id"]

    cr_resp = await client.post("/governance/complete/", json={
        "context_id": ctx_id, "outcome": "completed", "completed_at": "2026-01-01T00:00:00Z"})
    assert cr_resp.status_code == 200

    session_resp = await client.get(f"/governance/session/{ctx_id}/")
    assert session_resp.status_code == 200
    assert session_resp.json()["status"] == "consumed"
    assert session_resp.json()["completion_receipt"]["outcome"] == "completed"

@pytest.mark.asyncio
async def test_consumed_ac_rejected(client: AsyncClient, mocker):
    from gsap_broker.drivers.base import AuthResult
    mocker.patch("gsap_broker.drivers.keycloak.KeycloakDriver.authenticate",
                 return_value=AuthResult(status=AuthResult.STATUS_AUTHORIZED,
                                         principal_did="did:web:test/p/sam", token_jti="jti-2"))

    auth_resp = await client.post("/governance/authorize/", json={
        "playbook": "test", "corpus_entry_cid": "sha256:x", "parameters_cid": "sha256:y",
        "accord_template": "test", "driver_id": "keycloak"})
    ctx_id = auth_resp.json()["authorization_context"]["context_id"]

    await client.post("/governance/complete/", json={
        "context_id": ctx_id, "outcome": "completed", "completed_at": "2026-01-01T00:00:00Z"})

    second = await client.post("/governance/complete/", json={
        "context_id": ctx_id, "outcome": "completed", "completed_at": "2026-01-01T00:00:00Z"})
    assert second.status_code == 404
