"""Policy Engine: allow / deny / require_approval and workspace approval rules."""

from __future__ import annotations

from legate.agent.tooling import ToolSpec
from legate.policy.engine import ApprovalRules, PolicyEffect, evaluate_tool_call

SAFE = ToolSpec("kb.search", "", {"type": "object"}, is_sensitive=False)
SENSITIVE = ToolSpec("http.call", "", {"type": "object"}, is_sensitive=True)


def test_tool_outside_allowlist_is_denied():
    decision = evaluate_tool_call(tool=SAFE, allowed_tools=[])
    assert decision.effect is PolicyEffect.DENY


def test_non_sensitive_tool_is_allowed():
    decision = evaluate_tool_call(tool=SAFE, allowed_tools=["kb.search"])
    assert decision.effect is PolicyEffect.ALLOW
    assert not decision.auto_approved


def test_sensitive_tool_requires_approval_by_default():
    decision = evaluate_tool_call(tool=SENSITIVE, allowed_tools=["http.call"])
    assert decision.effect is PolicyEffect.REQUIRE_APPROVAL


def test_sensitive_tool_denied_by_workspace_rule():
    decision = evaluate_tool_call(
        tool=SENSITIVE, allowed_tools=["http.call"], rules=ApprovalRules(deny=["http.call"])
    )
    assert decision.effect is PolicyEffect.DENY


def test_sensitive_tool_auto_approved_by_workspace_rule():
    decision = evaluate_tool_call(
        tool=SENSITIVE, allowed_tools=["http.call"], rules=ApprovalRules(auto_approve=["http.call"])
    )
    assert decision.effect is PolicyEffect.ALLOW
    assert decision.auto_approved


def test_approval_rules_from_settings():
    rules = ApprovalRules.from_settings({"approval": {"auto_approve": ["a"], "deny": ["b"]}})
    assert rules.auto_approve == ["a"] and rules.deny == ["b"]
    empty = ApprovalRules.from_settings(None)
    assert empty.auto_approve == [] and empty.deny == []
