"""Tests for dependency classes."""


from pydanticai_multiagent.dependencies import (
    AuthDeps,
    BaseDeps,
    SearchDeps,
    create_mock_auth_deps,
    create_mock_base_deps,
    create_mock_search_deps,
)
from pydanticai_multiagent.dependencies.mocks import (
    MockCache,
    MockDatabase,
    MockHttpClient,
    MockVectorStore,
)


class TestBaseDeps:
    """Tests for BaseDeps."""

    def test_create_base_deps(self) -> None:
        """Test creating BaseDeps."""
        deps = BaseDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_id="test-user",
        )

        assert deps.user_id == "test-user"
        assert deps.http_client is not None
        assert deps.db is not None
        assert deps.cache is not None

    def test_with_user(self) -> None:
        """Test creating a copy with different user."""
        deps = BaseDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_id="user-1",
        )

        new_deps = deps.with_user("user-2")

        assert new_deps.user_id == "user-2"
        assert deps.user_id == "user-1"  # Original unchanged
        # Same underlying resources
        assert new_deps.http_client is deps.http_client
        assert new_deps.db is deps.db


class TestSearchDeps:
    """Tests for SearchDeps."""

    def test_create_search_deps(self) -> None:
        """Test creating SearchDeps."""
        deps = SearchDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            vector_store=MockVectorStore(),
            search_api_key="test-key",
            user_id="test-user",
        )

        assert deps.user_id == "test-user"
        assert deps.vector_store is not None
        assert deps.search_api_key == "test-key"
        assert deps.domain_toolset is None

    def test_to_base_deps(self) -> None:
        """Test converting SearchDeps to BaseDeps."""
        search_deps = SearchDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            vector_store=MockVectorStore(),
            search_api_key="test-key",
            user_id="test-user",
        )

        base_deps = search_deps.to_base_deps()

        assert isinstance(base_deps, BaseDeps)
        assert base_deps.user_id == "test-user"
        assert base_deps.http_client is search_deps.http_client
        assert not hasattr(base_deps, "vector_store") or getattr(base_deps, "vector_store", None) is None

    def test_to_auth_deps(self) -> None:
        """Test converting SearchDeps to AuthDeps."""
        search_deps = SearchDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            vector_store=MockVectorStore(),
            search_api_key="test-key",
            user_id="test-user",
        )

        auth_deps = search_deps.to_auth_deps(
            user_roles=["admin", "analyst"],
            permissions=["read:all"],
        )

        assert isinstance(auth_deps, AuthDeps)
        assert auth_deps.user_id == "test-user"
        assert auth_deps.user_roles == ["admin", "analyst"]
        assert auth_deps.permissions == ["read:all"]

    def test_from_base(self) -> None:
        """Test creating SearchDeps from BaseDeps."""
        base_deps = BaseDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_id="test-user",
        )
        vector_store = MockVectorStore()

        search_deps = SearchDeps.from_base(
            base_deps,
            vector_store=vector_store,
            search_api_key="test-key",
        )

        assert search_deps.user_id == "test-user"
        assert search_deps.vector_store is vector_store
        assert search_deps.search_api_key == "test-key"


class TestAuthDeps:
    """Tests for AuthDeps."""

    def test_create_auth_deps(self) -> None:
        """Test creating AuthDeps."""
        deps = AuthDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_id="test-user",
            user_roles=["admin"],
            permissions=["read:all", "write:all"],
        )

        assert deps.user_id == "test-user"
        assert "admin" in deps.user_roles
        assert "read:all" in deps.permissions

    def test_has_role(self) -> None:
        """Test role checking."""
        deps = AuthDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_roles=["admin", "analyst"],
            permissions=[],
        )

        assert deps.has_role("admin") is True
        assert deps.has_role("analyst") is True
        assert deps.has_role("superuser") is False

    def test_has_permission(self) -> None:
        """Test permission checking."""
        deps = AuthDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_roles=[],
            permissions=["read:data", "write:reports"],
        )

        assert deps.has_permission("read:data") is True
        assert deps.has_permission("write:reports") is True
        assert deps.has_permission("delete:all") is False

    def test_is_admin(self) -> None:
        """Test admin check."""
        admin_deps = AuthDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_roles=["admin"],
            permissions=[],
        )
        regular_deps = AuthDeps(
            http_client=MockHttpClient(),
            db=MockDatabase(),
            cache=MockCache(),
            user_roles=["user"],
            permissions=[],
        )

        assert admin_deps.is_admin() is True
        assert regular_deps.is_admin() is False


class TestMockFactories:
    """Tests for mock factory functions."""

    def test_create_mock_base_deps(self) -> None:
        """Test create_mock_base_deps factory."""
        deps = create_mock_base_deps()

        assert isinstance(deps, BaseDeps)
        assert deps.user_id == "test-user"
        assert isinstance(deps.http_client, MockHttpClient)
        assert isinstance(deps.db, MockDatabase)
        assert isinstance(deps.cache, MockCache)

    def test_create_mock_base_deps_custom_user(self) -> None:
        """Test create_mock_base_deps with custom user."""
        deps = create_mock_base_deps(user_id="custom-user")

        assert deps.user_id == "custom-user"

    def test_create_mock_search_deps(self) -> None:
        """Test create_mock_search_deps factory."""
        deps = create_mock_search_deps()

        assert isinstance(deps, SearchDeps)
        assert deps.user_id == "test-user"
        assert isinstance(deps.vector_store, MockVectorStore)
        assert deps.search_api_key == "mock-api-key"

    def test_create_mock_auth_deps(self) -> None:
        """Test create_mock_auth_deps factory."""
        deps = create_mock_auth_deps()

        assert isinstance(deps, AuthDeps)
        assert deps.user_id == "test-user"
        assert "user" in deps.user_roles
        assert "read:data" in deps.permissions

    def test_create_mock_auth_deps_custom(self) -> None:
        """Test create_mock_auth_deps with custom roles."""
        deps = create_mock_auth_deps(
            user_id="admin-user",
            roles=["admin", "superuser"],
            permissions=["all:all"],
        )

        assert deps.user_id == "admin-user"
        assert deps.user_roles == ["admin", "superuser"]
        assert deps.permissions == ["all:all"]
