"""Tests for multi-tenancy support."""

import pytest

from pyauthz import (
    ConfigError,
    Effect,
    PyAuthz,
    Resource,
    Role,
    Subject,
    TenantManager,
)
from pyauthz.models.policy import Policy


class TestTenantManager:
    def test_create_tenant_on_access(self):
        tm = TenantManager()
        storage = tm.get_storage("acme")
        assert tm.has_tenant("acme")
        assert storage is not None

    def test_separate_tenants_have_separate_roles(self):
        tm = TenantManager()
        tm.add_role(Role(name="admin", permissions=["*:*"]), tenant="acme")
        tm.add_role(Role(name="admin", permissions=["documents:read"]), tenant="globex")

        acme_roles = tm.get_storage("acme").get_roles()
        globex_roles = tm.get_storage("globex").get_roles()

        assert acme_roles["admin"].permissions == ["*:*"]
        assert globex_roles["admin"].permissions == ["documents:read"]

    def test_list_tenants(self):
        tm = TenantManager()
        tm.get_storage("a")
        tm.get_storage("b")
        tm.get_storage("c")
        assert sorted(tm.list_tenants()) == ["a", "b", "c"]

    def test_remove_tenant(self):
        tm = TenantManager()
        tm.get_storage("acme")
        tm.remove_tenant("acme")
        assert not tm.has_tenant("acme")

    def test_remove_nonexistent_tenant_raises(self):
        tm = TenantManager()
        with pytest.raises(ConfigError, match="not found"):
            tm.remove_tenant("nope")

    def test_add_policy_to_tenant(self):
        tm = TenantManager()
        tm.add_policy(
            Policy(name="allow-read", effect=Effect.ALLOW, permissions=["documents:read"]),
            tenant="acme",
        )
        policies = tm.get_storage("acme").get_policies()
        assert len(policies) == 1
        assert policies[0].name == "allow-read"

    def test_tenant_isolation_with_engine(self):
        """Verify tenant-scoped storage works with the engine."""
        tm = TenantManager()
        tm.add_role(Role(name="admin", permissions=["*:*"]), tenant="acme")
        tm.add_role(Role(name="viewer", permissions=["documents:read"]), tenant="globex")

        rp_acme = PyAuthz(storage=tm.get_storage("acme"))
        rp_globex = PyAuthz(storage=tm.get_storage("globex"))

        user = Subject(id="alice", roles=["admin"])
        doc = Resource(id="doc-1", type="documents")

        # Admin can write in acme
        assert rp_acme.is_allowed(user, "write", doc)

        # Admin role doesn't exist in globex — only viewer does
        viewer = Subject(id="alice", roles=["viewer"])
        assert rp_globex.is_allowed(viewer, "read", doc)
        assert not rp_globex.is_allowed(viewer, "write", doc)
