import pytest

from rgltr.config import configure
from rgltr.governance import evaluate_policies
from rgltr.types import PolicyDecision, PolicyRequest, PolicySet, ToolRules


async def allow_policy(_: PolicyRequest) -> PolicyDecision:
    return PolicyDecision.allow("ok")


async def deny_policy(_: PolicyRequest) -> PolicyDecision:
    return PolicyDecision.deny("nope")


async def approval_policy(_: PolicyRequest) -> PolicyDecision:
    return PolicyDecision.requires_approval("approve")


@pytest.mark.anyio
async def test_policy_require_denies():
    rules = ToolRules(policies=PolicySet(require=(deny_policy,)))
    decision = await evaluate_policies(rules, _request())
    assert decision.outcome == "deny"


@pytest.mark.anyio
async def test_policy_any_of_allows():
    rules = ToolRules(policies=PolicySet(any_of=(deny_policy, allow_policy)))
    decision = await evaluate_policies(rules, _request())
    assert decision.outcome == "allow"


@pytest.mark.anyio
async def test_policy_requires_approval():
    rules = ToolRules(policies=PolicySet(require=(approval_policy,)))
    decision = await evaluate_policies(rules, _request())
    assert decision.outcome == "approval"


@pytest.mark.anyio
async def test_monitor_mode_still_reports_denial():
    configure(mode="monitor")
    rules = ToolRules(policies=PolicySet(require=(deny_policy,)))
    decision = await evaluate_policies(rules, _request())
    assert decision.outcome == "deny"


def _request() -> PolicyRequest:
    return PolicyRequest(
        tool_name="t",
        args={},
        active_tags=set(),
        boundary=None,
        agent_id=None,
        run_id="r1",
        run_context=None,
    )
