from abc import ABC, abstractmethod
from typing import List

from xulcan.protocol.message import UnifiedMessage
from xulcan.protocol.io import UnifiedResponse
from xulcan.protocol.tools import ToolDefinition

from xulcan.kernel.interfaces import LLMProvider

class BaseLLMAdapter(LLMProvider, ABC):
    """Abstract base class for LLM providers."""
    
    def __init__(self, **kwargs):
        self.config = kwargs

    async def generate(
        self,
        model: str,
        messages: List[UnifiedMessage],
        tools: List[ToolDefinition] | None = None,
        temperature: float = 0.0,
        max_tokens: int | None = None,
        **kwargs,
    ) -> UnifiedResponse:
        """Template method that delegates to provider-specific implementation."""
        # Aquí en el futuro podrías añadir logs automáticos para todos los LLMs
        
        return await self._generate_impl(
            model=model,
            messages=messages,
            tools=tools,
            temperature=temperature,
            max_tokens=max_tokens,
            **kwargs
        )

    @abstractmethod
    async def _generate_impl(
        self,
        model: str,
        messages: List[UnifiedMessage],
        tools: List[ToolDefinition] | None,
        temperature: float,
        max_tokens: int | None,
        **kwargs,
    ) -> UnifiedResponse:
        """Specific implementation to be overridden by subclasses (Gemini, OpenAI, etc)."""
        pass