"""Frozen backend - errors on any generation attempt.

This backend is used when code generation should be disabled and only cached methods
should be used. Any attempt to generate new code will raise FrozenAppError.
"""

from typing import Optional

from scry_run.backends.base import GeneratorBackend, GeneratedCode
from scry_run.backends.registry import register_backend


class FrozenAppError(RuntimeError):
    """Raised when a frozen app attempts to generate code.

    This error indicates that a method was called that doesn't exist
    in the cache of a frozen app. The backend needs to be changed to allow
    generation, or the method needs to be pre-generated and cached.
    """

    def __init__(self, class_name: str, attr_name: str):
        self.class_name = class_name
        self.attr_name = attr_name
        super().__init__(
            f"Frozen app cannot generate code for '{class_name}.{attr_name}'. "
            f"This method is not in the cache. Either:\n"
            f"  1. Run the app with a real backend to generate this method first\n"
            f"  2. Set _llm_backend to a real backend (e.g., 'claude') to unfreeze"
        )


class FrozenBackend(GeneratorBackend):
    """Backend that refuses to generate any code.

    Used when all methods should come from cache and generation is disabled.
    Any generation attempt raises FrozenAppError with helpful message.
    """

    name = "frozen"

    def __init__(self, model: Optional[str] = None):
        """Initialize frozen backend.

        Args:
            model: Ignored (frozen backend doesn't use models)
        """
        self.model = model
        # Store context about what's being generated for error messages
        self._current_class: Optional[str] = None
        self._current_attr: Optional[str] = None

    @classmethod
    def is_available(cls) -> bool:
        """Frozen backend is always available."""
        return True

    def generate_text(self, prompt: str) -> str:
        """Raise error - frozen apps cannot generate text."""
        raise FrozenAppError(
            self._current_class or "Unknown",
            self._current_attr or "unknown"
        )

    def generate_code(self, prompt: str) -> GeneratedCode:
        """Raise error - frozen apps cannot generate code."""
        raise FrozenAppError(
            self._current_class or "Unknown",
            self._current_attr or "unknown"
        )

    def set_generation_context(self, class_name: str, attr_name: str) -> None:
        """Set context for error messages.

        Called by the generator before attempting generation.

        Args:
            class_name: Name of the class being generated for
            attr_name: Name of the attribute being generated
        """
        self._current_class = class_name
        self._current_attr = attr_name


# Register the backend
register_backend("frozen", FrozenBackend)
