"""Expression caching service for metadata stage."""

import polars as pl
from typing import Dict, List
import logging

from ..config import ProviderConfig

logger = logging.getLogger(__name__)


class ExpressionCache:
    """
    Caches Polars expressions by provider.

    Single responsibility: Cache management for expressions.
    Does NOT build expressions - that's ExpressionBuilder's job.
    Does NOT apply expressions - that's MetadataProcessor's job.
    """

    def __init__(self, builder: 'ExpressionBuilder'):
        """
        Initialize cache with expression builder.

        Args:
            builder: ExpressionBuilder to use when cache misses
        """
        self.builder = builder
        self._cache: Dict[str, Dict[str, List[pl.Expr]]] = {}

    def get_expressions(
        self,
        provider: str,
        provider_config: ProviderConfig,
        df: pl.DataFrame = None
    ) -> Dict[str, List[pl.Expr]]:
        """
        Get expressions for provider (cached or freshly built).

        Returns dictionary with:
        - 'resource_id': Expressions that must be applied sequentially
        - 'batch': Expressions that can be applied together

        Args:
            provider: Provider name (e.g., "aws", "azure")
            provider_config: Provider configuration
            df: Optional DataFrame (required for four-group expressions)

        Returns:
            Dictionary with 'resource_id' and 'batch' expression lists
        """
        if provider not in self._cache:
            # Cache miss - build and cache
            expressions = self.builder.build_expressions_for_provider(
                provider_config, provider, df
            )
            self._cache[provider] = expressions
            logger.debug(
                f"Expression cache MISS for {provider} - "
                f"built {len(expressions['resource_id'])} resource_id + "
                f"{len(expressions['batch'])} batch expressions"
            )
        else:
            # Cache hit
            expressions = self._cache[provider]
            logger.debug(
                f"Expression cache HIT for {provider} - "
                f"using {len(expressions['resource_id'])} resource_id + "
                f"{len(expressions['batch'])} cached expressions"
            )

        return expressions

    def clear(self):
        """Clear all cached expressions."""
        self._cache.clear()
        logger.debug("Expression cache cleared")

    def get_cache_stats(self) -> Dict[str, int]:
        """
        Get cache statistics.

        Returns:
            Dictionary with cache stats (providers cached, total expressions)
        """
        total_resource_id = sum(
            len(exprs['resource_id']) for exprs in self._cache.values()
        )
        total_batch = sum(
            len(exprs['batch']) for exprs in self._cache.values()
        )
        return {
            "providers_cached": len(self._cache),
            "total_resource_id_expressions": total_resource_id,
            "total_batch_expressions": total_batch,
            "total_expressions": total_resource_id + total_batch
        }
