from pathlib import Path
import yaml

from .models import TenantConfig

from .models import (
    OidcBffConfig,
    EmailConfig,
    PagopaConfig,
    ProtocolloConfig,
)
from .resolvers import (
    resolve_oidc_config,
    resolve_email_config,
    resolve_pagopa_config,
    resolve_protocollo_config,
)

class TenantConfigService:
    def __init__(self, secret_dir: str):
        self.secret_dir = Path(secret_dir)
        self._cache: dict[str, TenantConfig] = {}

    def _load_tenant_config(self, tenant: str) -> TenantConfig:
        file = self.secret_dir / f"{tenant}.yaml"

        if not file.exists():
            raise FileNotFoundError(f"Tenant config '{tenant}' non trovato")

        data = yaml.safe_load(file.read_text())

        return TenantConfig(**data)

    def get(self, tenant: str) -> TenantConfig:
        if tenant not in self._cache:
            self._cache[tenant] = self._load_tenant_config(tenant)
        return self._cache[tenant]

    def list_tenants(self) -> list[str]:
        return [p.stem for p in self.secret_dir.glob("*.yaml")]

    def invalidate(self, tenant: str | None = None):
        if tenant is None:
            self._cache.clear()
        else:
            self._cache.pop(tenant, None)
            
            
from .models import (
    OidcBffConfig,
    EmailConfig,
    PagopaConfig,
    ProtocolloConfig,
)
from .resolvers import (
    resolve_oidc_config,
    resolve_email_config,
    resolve_pagopa_config,
    resolve_protocollo_config,
)


class TenantRuntimeConfigService:
    def __init__(self, tenant_service, settings):
        self.tenant_service = tenant_service
        self.settings = settings

        self._oidc_cache: dict[str, OidcBffConfig] = {}
        self._email_cache: dict[str, EmailConfig] = {}
        self._pagopa_cache: dict[str, PagopaConfig] = {}
        self._protocollo_cache: dict[str, ProtocolloConfig] = {}

    # -------------------------
    # OIDC
    # -------------------------

    def get_oidc(self, tenant: str) -> OidcBffConfig:
        if tenant not in self._oidc_cache:
            tenant_cfg = self.tenant_service.get(tenant)
            self._oidc_cache[tenant] = OidcBffConfig(
                **resolve_oidc_config(tenant_cfg, self.settings)
            )
        return self._oidc_cache[tenant]

    # -------------------------
    # EMAIL
    # -------------------------

    def get_email(self, tenant: str) -> EmailConfig:
        if tenant not in self._email_cache:
            tenant_cfg = self.tenant_service.get(tenant)
            self._email_cache[tenant] = EmailConfig(
                **resolve_email_config(tenant_cfg, self.settings)
            )
        return self._email_cache[tenant]

    # -------------------------
    # PAGOPA
    # -------------------------

    def get_pagopa(self, tenant: str) -> PagopaConfig:
        if tenant not in self._pagopa_cache:
            tenant_cfg = self.tenant_service.get(tenant)
            self._pagopa_cache[tenant] = PagopaConfig(
                **resolve_pagopa_config(tenant_cfg, self.settings)
            )
        return self._pagopa_cache[tenant]

    # -------------------------
    # PROTOCOLLO
    # -------------------------

    def get_protocollo(self, tenant: str) -> ProtocolloConfig:
        if tenant not in self._protocollo_cache:
            tenant_cfg = self.tenant_service.get(tenant)
            self._protocollo_cache[tenant] = ProtocolloConfig(
                **resolve_protocollo_config(tenant_cfg, self.settings)
            )
        return self._protocollo_cache[tenant]

    # -------------------------
    # INVALIDATE
    # -------------------------

    def invalidate(self, tenant: str | None = None):
        caches = [
            self._oidc_cache,
            self._email_cache,
            self._pagopa_cache,
            self._protocollo_cache,
        ]

        if tenant is None:
            for cache in caches:
                cache.clear()
        else:
            for cache in caches:
                cache.pop(tenant, None)