"""Agent Runtime Operator Configuration.

Provides dataclass-based configuration for AgentRuntimeOperator.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Literal


@dataclass
class GeneratorConfig:
    """Generator configuration for agent LLM calls.

    Attributes:
        engine_type: Engine type to use:
            - "sagellm" (default): SageLLMGenerator via OpenAI-compatible inference service port
            - "openai": OpenAIGenerator for OpenAI-compatible APIs
            - "hf": HFGenerator for HuggingFace models
        model_path: Model path or HuggingFace model ID (sagellm only)
        base_url: SageLLM/OpenAI-compatible inference service URL (sagellm/openai)
        api_key: API key (sagellm/openai)
        max_tokens: Maximum generation tokens
        temperature: Sampling temperature
        top_p: Nucleus sampling parameter
        top_k: Top-k sampling parameter
        timeout: Request timeout in seconds
        default_options: Default generation options
        model_name: Model name for OpenAI (openai only)
    """

    engine_type: Literal["sagellm", "openai", "hf"] = "sagellm"

    # SageLLM options
    model_path: str = ""
    base_url: str = ""
    api_key: str = ""
    max_tokens: int = 2048
    temperature: float = 0.7
    top_p: float = 0.95
    top_k: int = 50
    timeout: float = 120.0
    default_options: dict[str, Any] = field(default_factory=dict)

    # OpenAI-only options
    model_name: str = ""

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for operator initialization."""
        return {
            "engine_type": self.engine_type,
            "model_path": self.model_path,
            "base_url": self.base_url,
            "api_key": self.api_key,
            "max_tokens": self.max_tokens,
            "temperature": self.temperature,
            "top_p": self.top_p,
            "top_k": self.top_k,
            "timeout": self.timeout,
            "default_options": self.default_options,
            "model_name": self.model_name,
        }


@dataclass
class ProfileConfig:
    """Agent profile configuration.

    Attributes:
        name: Agent name
        description: Agent description
        role: Agent role (assistant/user/system)
        system_prompt: System prompt for the agent
    """

    name: str = "DefaultAgent"
    description: str = "A general-purpose AI assistant"
    role: str = "assistant"
    system_prompt: str = "You are a helpful assistant."

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for operator initialization."""
        return {
            "name": self.name,
            "description": self.description,
            "role": self.role,
            "system_prompt": self.system_prompt,
        }


@dataclass
class RuntimeSettings:
    """Runtime settings for agent execution.

    Attributes:
        max_steps: Maximum execution steps
        summarizer: Summarizer config (null/"reuse_generator"/dict)
    """

    max_steps: int = 6
    summarizer: str | dict[str, Any] | None = "reuse_generator"

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for operator initialization."""
        return {
            "max_steps": self.max_steps,
            "summarizer": self.summarizer,
        }


@dataclass
class AgentRuntimeConfig:
    """Complete configuration for AgentRuntimeOperator.

    Example:
        ```python
        # Create config with default SageLLM inference port mode
        config = AgentRuntimeConfig(
            generator=GeneratorConfig(
                engine_type="sagellm",
                model_path="Qwen/Qwen2.5-7B-Instruct",
            ),
            profile=ProfileConfig(name="TestBot"),
        )
        operator = AgentRuntimeOperator(config=config.to_dict())

        # Create config with OpenAI
        config = AgentRuntimeConfig(
            generator=GeneratorConfig(
                engine_type="openai",
                model_name="gpt-4o-mini",
                api_key="EMPTY",  # placeholder — set via env or config at runtime
            ),
        )
        ```

    Attributes:
        generator: Generator configuration
        profile: Agent profile configuration
        planner: Planner configuration (optional)
        tools: List of tool specifications
        runtime: Runtime settings
    """

    generator: GeneratorConfig = field(default_factory=GeneratorConfig)
    profile: ProfileConfig = field(default_factory=ProfileConfig)
    planner: dict[str, Any] = field(default_factory=dict)
    tools: list[dict[str, Any]] = field(default_factory=list)
    runtime: RuntimeSettings = field(default_factory=RuntimeSettings)

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for operator initialization."""
        return {
            "generator": self.generator.to_dict(),
            "profile": self.profile.to_dict(),
            "planner": self.planner,
            "tools": self.tools,
            "runtime": self.runtime.to_dict(),
        }

    @classmethod
    def for_mock_testing(cls, profile_name: str = "TestBot") -> AgentRuntimeConfig:
        """Create a configuration for service-port testing.

        Args:
            profile_name: Name for the test agent profile

        Returns:
            AgentRuntimeConfig configured for default SageLLM service path
        """
        return cls(
            generator=GeneratorConfig(
                engine_type="sagellm",
            ),
            profile=ProfileConfig(name=profile_name),
        )

    @classmethod
    def for_openai(
        cls,
        model_name: str = "gpt-4o-mini",
        api_key: str = "",
        base_url: str = "https://api.openai.com/v1",
        profile_name: str = "OpenAIAgent",
    ) -> AgentRuntimeConfig:
        """Create a configuration for OpenAI.

        Args:
            model_name: OpenAI model name
            api_key: OpenAI API key
            base_url: API base URL
            profile_name: Name for the agent profile

        Returns:
            AgentRuntimeConfig configured for OpenAI
        """
        return cls(
            generator=GeneratorConfig(
                engine_type="openai",
                model_name=model_name,
                api_key=api_key,
                base_url=base_url,
            ),
            profile=ProfileConfig(name=profile_name),
        )

    @classmethod
    def for_sagellm(
        cls,
        model_path: str,
        base_url: str = "",
        profile_name: str = "SageLLMAgent",
    ) -> AgentRuntimeConfig:
        """Create a configuration for SageLLM.

        Args:
            model_path: Model path or HuggingFace model ID
            base_url: Optional inference service base URL
            profile_name: Name for the agent profile

        Returns:
            AgentRuntimeConfig configured for SageLLM
        """
        return cls(
            generator=GeneratorConfig(
                engine_type="sagellm",
                model_path=model_path,
                base_url=base_url,
            ),
            profile=ProfileConfig(name=profile_name),
        )


__all__ = [
    "AgentRuntimeConfig",
    "GeneratorConfig",
    "ProfileConfig",
    "RuntimeSettings",
]
