"""
Unit tests for PolicyResolver - tests guardrail resolution.

Tests:
- Inheritance chain resolution
- Inheritance with add/remove
- Model conditions
"""

import pytest

from litellm.proxy.policy_engine.policy_resolver import PolicyResolver
from litellm.types.proxy.policy_engine import (
    Policy,
    PolicyCondition,
    PolicyGuardrails,
    PolicyMatchContext,
)


class TestPolicyResolverInheritance:
    """Test resolve_policy_guardrails - inheritance and add/remove."""

    def test_resolve_simple_policy(self):
        """Test resolving guardrails for a simple policy."""
        policies = {
            "global": Policy(
                guardrails=PolicyGuardrails(add=["pii_blocker", "toxicity_filter"]),
            ),
        }

        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="global", policies=policies
        )

        assert set(resolved.guardrails) == {"pii_blocker", "toxicity_filter"}
        assert resolved.inheritance_chain == ["global"]

    def test_resolve_with_inheritance(self):
        """Test child policy inherits and adds guardrails from parent."""
        policies = {
            "base": Policy(
                guardrails=PolicyGuardrails(add=["pii_blocker"]),
            ),
            "healthcare": Policy(
                inherit="base",
                guardrails=PolicyGuardrails(add=["hipaa_audit"]),
            ),
        }

        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="healthcare", policies=policies
        )

        # Healthcare inherits pii_blocker from base and adds hipaa_audit
        assert set(resolved.guardrails) == {"pii_blocker", "hipaa_audit"}
        assert resolved.inheritance_chain == ["base", "healthcare"]

    def test_resolve_with_remove(self):
        """Test child policy can remove guardrails from parent."""
        policies = {
            "base": Policy(
                guardrails=PolicyGuardrails(add=["pii_blocker", "phi_blocker"]),
            ),
            "dev": Policy(
                inherit="base",
                guardrails=PolicyGuardrails(
                    add=["toxicity_filter"], remove=["phi_blocker"]
                ),
            ),
        }

        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="dev", policies=policies
        )

        # dev inherits pii_blocker from base, adds toxicity_filter, removes phi_blocker
        assert "pii_blocker" in resolved.guardrails
        assert "toxicity_filter" in resolved.guardrails
        assert "phi_blocker" not in resolved.guardrails

    def test_resolve_deep_inheritance_chain(self):
        """Test multi-level inheritance chain."""
        policies = {
            "root": Policy(
                guardrails=PolicyGuardrails(add=["root_guardrail"]),
            ),
            "middle": Policy(
                inherit="root",
                guardrails=PolicyGuardrails(add=["middle_guardrail"]),
            ),
            "leaf": Policy(
                inherit="middle",
                guardrails=PolicyGuardrails(add=["leaf_guardrail"]),
            ),
        }

        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="leaf", policies=policies
        )

        assert set(resolved.guardrails) == {
            "root_guardrail",
            "middle_guardrail",
            "leaf_guardrail",
        }
        assert resolved.inheritance_chain == ["root", "middle", "leaf"]


class TestPolicyResolverWithConditions:
    """Test resolve_policy_guardrails with model conditions."""

    def test_condition_matches(self):
        """Test guardrails are added when condition matches."""
        policies = {
            "gpt4-policy": Policy(
                guardrails=PolicyGuardrails(add=["toxicity_filter"]),
                condition=PolicyCondition(model="gpt-4.*"),
            ),
        }

        # GPT-4 should get guardrails
        context = PolicyMatchContext(team_alias="team", key_alias="k", model="gpt-4")
        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="gpt4-policy",
            policies=policies,
            context=context,
        )

        assert "toxicity_filter" in resolved.guardrails

    def test_condition_does_not_match(self):
        """Test guardrails are NOT added when condition doesn't match."""
        policies = {
            "gpt4-policy": Policy(
                guardrails=PolicyGuardrails(add=["toxicity_filter"]),
                condition=PolicyCondition(model="gpt-4.*"),
            ),
        }

        # GPT-3.5 should NOT get guardrails
        context = PolicyMatchContext(team_alias="team", key_alias="k", model="gpt-3.5")
        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="gpt4-policy",
            policies=policies,
            context=context,
        )

        assert "toxicity_filter" not in resolved.guardrails

    def test_no_condition_always_applies(self):
        """Test policy without condition always applies."""
        policies = {
            "global": Policy(
                guardrails=PolicyGuardrails(add=["pii_blocker"]),
            ),
        }

        context = PolicyMatchContext(team_alias="any", key_alias="any", model="any")
        resolved = PolicyResolver.resolve_policy_guardrails(
            policy_name="global",
            policies=policies,
            context=context,
        )

        assert "pii_blocker" in resolved.guardrails

    def test_inheritance_with_condition(self):
        """Test inheritance works with conditions."""
        policies = {
            "base": Policy(
                guardrails=PolicyGuardrails(add=["pii_blocker"]),
            ),
            "child": Policy(
                inherit="base",
                guardrails=PolicyGuardrails(add=["child_guardrail"]),
                condition=PolicyCondition(model="gpt-4"),
            ),
        }

        # GPT-4 should get both base and child guardrails
        context_gpt4 = PolicyMatchContext(team_alias="t", key_alias="k", model="gpt-4")
        resolved_gpt4 = PolicyResolver.resolve_policy_guardrails(
            policy_name="child",
            policies=policies,
            context=context_gpt4,
        )
        assert "pii_blocker" in resolved_gpt4.guardrails
        assert "child_guardrail" in resolved_gpt4.guardrails

        # GPT-3.5 should only get base guardrails (child condition doesn't match)
        context_gpt35 = PolicyMatchContext(
            team_alias="t", key_alias="k", model="gpt-3.5"
        )
        resolved_gpt35 = PolicyResolver.resolve_policy_guardrails(
            policy_name="child",
            policies=policies,
            context=context_gpt35,
        )
        assert "pii_blocker" in resolved_gpt35.guardrails
        assert "child_guardrail" not in resolved_gpt35.guardrails
