"""Tests for storage backends."""

import pytest

from pyauthz import ConfigError, Effect, Policy, Role
from pyauthz.storage.memory import MemoryStorage


class TestMemoryStorage:
    def test_add_and_get_policies(self):
        store = MemoryStorage()
        p = Policy(name="test", effect=Effect.ALLOW)
        store.add_policy(p)
        policies = store.get_policies()
        assert len(policies) == 1
        assert policies[0].name == "test"

    def test_add_duplicate_policy_raises(self):
        store = MemoryStorage()
        p = Policy(name="test", effect=Effect.ALLOW)
        store.add_policy(p)
        with pytest.raises(ConfigError, match="already exists"):
            store.add_policy(p)

    def test_remove_policy(self):
        store = MemoryStorage()
        store.add_policy(Policy(name="test", effect=Effect.ALLOW))
        store.remove_policy("test")
        assert store.get_policies() == []

    def test_remove_nonexistent_policy_raises(self):
        store = MemoryStorage()
        with pytest.raises(ConfigError, match="not found"):
            store.remove_policy("nope")

    def test_replace_policies(self):
        store = MemoryStorage()
        store.add_policy(Policy(name="old", effect=Effect.DENY))
        store.replace_policies([Policy(name="new", effect=Effect.ALLOW)])
        policies = store.get_policies()
        assert len(policies) == 1
        assert policies[0].name == "new"

    def test_add_and_get_roles(self):
        store = MemoryStorage()
        store.add_role(Role(name="admin", permissions=["*:*"]))
        roles = store.get_roles()
        assert "admin" in roles

    def test_add_duplicate_role_raises(self):
        store = MemoryStorage()
        store.add_role(Role(name="admin"))
        with pytest.raises(ConfigError, match="already exists"):
            store.add_role(Role(name="admin"))

    def test_remove_role(self):
        store = MemoryStorage()
        store.add_role(Role(name="admin"))
        store.remove_role("admin")
        assert store.get_roles() == {}

    def test_remove_nonexistent_role_raises(self):
        store = MemoryStorage()
        with pytest.raises(ConfigError, match="not found"):
            store.remove_role("nope")

    def test_replace_roles(self):
        store = MemoryStorage()
        store.add_role(Role(name="old"))
        store.replace_roles([Role(name="new")])
        roles = store.get_roles()
        assert "new" in roles
        assert "old" not in roles

    def test_get_policies_returns_copy(self):
        store = MemoryStorage()
        store.add_policy(Policy(name="test", effect=Effect.ALLOW))
        policies = store.get_policies()
        policies.clear()
        assert len(store.get_policies()) == 1

    def test_get_roles_returns_copy(self):
        store = MemoryStorage()
        store.add_role(Role(name="admin"))
        roles = store.get_roles()
        roles.clear()
        assert len(store.get_roles()) == 1
