"""
Timing Operator

Middleware operator for timing decisions using runtime components.

Supports engine_type switching:
- sagellm (default): SageLLMGenerator via single inference service port
- openai: OpenAIGenerator for OpenAI-compatible APIs
- hf: HFGenerator for HuggingFace models
"""

from typing import Any

from sage.common.core.functions import MapFunction

from .runtime import _build_generator


class TimingOperator(MapFunction):
    """
    Operator for timing decisions.

    Wraps runtime timing decider in a middleware operator interface.

    Args:
        timing_decider: Timing decider instance (optional)
        config: Configuration dictionary with optional keys:
            - timing: Timing-specific config
            - generator: Generator config with engine_type
            - engine_type: Shorthand for generator.engine_type (sagellm/openai/hf)

    Example:
        ```python
        # Using sagellm service-port mode
        operator = TimingOperator(config={
            "generator": {
                "engine_type": "sagellm",
                "model_path": "Qwen/Qwen2.5-7B-Instruct",
            },
        })

        # Using default sagellm mode
        operator = TimingOperator(config={
            "engine_type": "sagellm",
        })
        ```
    """

    def __init__(
        self,
        timing_decider: Any | None = None,
        config: dict[str, Any] | None = None,
    ):
        """Initialize timing operator.

        Args:
            timing_decider: Timing decider instance (optional)
            config: Configuration dictionary
        """
        super().__init__()

        # Parse configuration
        if config is None:
            config = {}

        self.config = config

        # Build generator if config provided
        generator_conf = config.get("generator", {})
        # Allow shorthand engine_type at top level
        if "engine_type" in config and "engine_type" not in generator_conf:
            generator_conf["engine_type"] = config["engine_type"]

        # Build generator (defaults to sagellm service-port mode)
        if generator_conf or not timing_decider:
            engine_type = generator_conf.get("engine_type", "sagellm")
            # Ensure we have at least minimal config
            if not generator_conf:
                generator_conf = {"engine_type": "sagellm"}
            self.generator = _build_generator(generator_conf, engine_type=engine_type)
        else:
            self.generator = None

        try:
            from sage_libs.sage_agentic.agents.runtime import (
                BenchmarkAdapter,
                Orchestrator,
                RuntimeConfig,
            )
            from sage_libs.sage_agentic.agents.runtime.config import TimingConfig
        except ImportError as exc:
            raise ImportError(
                "TimingOperator requires 'isage-agentic'. "
                "Install it with: pip install isage-agentic"
            ) from exc
        timing_config = TimingConfig(**config.get("timing", {}))
        runtime_config = RuntimeConfig(timing=timing_config)

        # Create orchestrator
        self.orchestrator = Orchestrator(config=runtime_config, timing_decider=timing_decider)

        # Create adapter for easy use
        self.adapter = BenchmarkAdapter(self.orchestrator)

    def __call__(self, message: Any) -> Any:
        """Execute timing decision.

        Args:
            message: Message to evaluate

        Returns:
            Timing decision
        """
        return self.adapter.run_timing(message)

    def execute(self, data: Any) -> Any:
        """Execute map function interface."""
        return self.__call__(data)

    def get_metrics(self) -> dict[str, Any]:
        """Get performance metrics.

        Returns:
            Dictionary of metrics
        """
        return self.adapter.get_metrics()
