from typing import Annotated

import pytest

from zayt.di.container import Container
from zayt.di.error import (
    IncompatibleDependencyScopeError,
    ScopedServiceWithoutContextError,
)
from zayt.di.inject import Inject


async def test_service_with_different_scope(ioc: Container):
    class ApplicationScopedService:
        pass

    class ContextScopedService:
        dependency: Annotated[ApplicationScopedService, Inject]

    ioc.register(ApplicationScopedService)
    ioc.register(ContextScopedService, scoped=True)

    context = object()

    result = await ioc.get(ContextScopedService, context=context)
    assert isinstance(result.dependency, ApplicationScopedService)


async def test_get_context_scoped_service_without_context_should_fail(ioc: Container):
    class ContextScopedService:
        pass

    ioc.register(ContextScopedService, scoped=True)

    with pytest.raises(ScopedServiceWithoutContextError):
        await ioc.get(ContextScopedService)


async def test_service_with_incompatible_scoped_dependency_should_fail(
    ioc: Container,
):
    class ContextScopedService:
        pass

    class ApplicationScopedService:
        dependency: Annotated[ContextScopedService, Inject]

    ioc.register(ContextScopedService, scoped=True)
    ioc.register(ApplicationScopedService)

    with pytest.raises(IncompatibleDependencyScopeError):
        await ioc.get(ApplicationScopedService)
