import os
from abc import ABC
from typing import Callable, List

from edpconfigprovider import ConfigProvider, FallbackConfigProvider
from edpconfigprovider.parameters import ProviderParameters

from ._builder_registry import get_provider


class ProviderBuilder(ABC):
    @staticmethod
    def get_provider_type() -> str:
        provider_type_env = os.environ["CONFIG_PROVIDER_TYPE"]
        return provider_type_env.lower()

    @staticmethod
    def get_provider_types() -> List[str]:
        provider_type_env = os.environ["CONFIG_PROVIDER_TYPE"]
        return [t.strip().lower() for t in provider_type_env.split(",")]

    def build_provider(self, **kwargs) -> ConfigProvider:
        provider_types = self.get_provider_types()

        if len(provider_types) == 1:
            return self._build_single_provider(provider_types[0], **kwargs)

        providers = [self._build_single_provider(pt, **kwargs) for pt in provider_types]
        return FallbackConfigProvider(providers)

    def _build_single_provider(self, provider_type: str, **kwargs) -> ConfigProvider:
        provider = get_provider(provider_type)

        if provider is None:
            raise ValueError(f"Provider Type not implemented: {provider_type}")

        if isinstance(provider, Callable):
            provider = provider(self.get_provider_parameters(**kwargs))
        return provider

    def get_provider_parameters(self, **_kwargs) -> ProviderParameters:
        return ProviderParameters()
