from reactivex import operators as ops, Observable
from reactivex.subject import ReplaySubject

from clochette import log
from clochette.application.service.provider.dto.ProviderDTO import ProviderDTO
from clochette.application.service.provider.dto.ProviderType import ProviderType


class ProviderStore:
    """Store for available provider information."""

    _providers: ReplaySubject[list[ProviderDTO]]

    def __init__(self):
        self._providers = ReplaySubject(buffer_size=1)

    @property
    def providers(self) -> Observable[list[ProviderDTO]]:
        return self._providers

    def set_provider(self, providers: list[ProviderDTO]) -> None:
        self._providers.on_next(providers)

    def get_by_type(self, provider_type: ProviderType) -> Observable[ProviderDTO]:

        def find(providers: list[ProviderDTO]) -> ProviderDTO:
            for provider_dto in providers:
                if provider_dto.provider_type == provider_type:
                    return provider_dto
            log.error(f"No provider found for provider type: {provider_type.get_id()}")
            raise Exception(f"No provider found for provider type: {provider_type.get_id()}")

        return self._providers.pipe(
            ops.take(1),
            ops.map(lambda provider: find(provider)),
        )
