# app/src/trading/market_intelligence/runtime/validation.py

from __future__ import annotations

from src.trading.market_intelligence.common.models import EngineRegistration
from src.trading.market_intelligence.common.types import EngineName
from src.trading.market_intelligence.runtime.dependencies import RuntimeDependencies
from src.trading.market_intelligence.runtime.exceptions import (
    DuplicateEngineRegistrationError,
    EmptyRuntimeRegistryError,
    InvalidEngineMetadataError,
)
from src.trading.market_intelligence.runtime.registry import RuntimeRegistry


class RuntimeValidation:
    """Проверка корректности Runtime перед запуском."""

    def __init__(self) -> None:
        """Создать Runtime Validation."""
        self._dependencies = RuntimeDependencies()

    def validate(
        self,
        registry: RuntimeRegistry,
    ) -> None:
        """Проверить готовность Runtime."""
        registrations = registry.list()

        self._validate_registry(registrations)
        self._validate_metadata(registrations)
        self._validate_duplicates(registrations)

        self._dependencies.resolve(registrations)

    def _validate_registry(
        self,
        registrations: tuple[EngineRegistration, ...],
    ) -> None:
        """Проверить, что Registry не пуст."""
        if not registrations:
            raise EmptyRuntimeRegistryError(
                "Runtime Registry does not contain registered Engine."
            )

    def _validate_metadata(
        self,
        registrations: tuple[EngineRegistration, ...],
    ) -> None:
        """Проверить корректность metadata Engine."""
        for registration in registrations:
            metadata = registration.metadata

            if not metadata.name:
                raise InvalidEngineMetadataError(
                    "Engine name is not specified."
                )

            if not metadata.version:
                raise InvalidEngineMetadataError(
                    f"Engine '{metadata.name}' has no version."
                )

    def _validate_duplicates(
        self,
        registrations: tuple[EngineRegistration, ...],
    ) -> None:
        """Проверить отсутствие повторной регистрации Engine."""
        names: set[EngineName] = set()

        for registration in registrations:
            engine_name = registration.metadata.name

            if engine_name in names:
                raise DuplicateEngineRegistrationError(
                    f"Duplicate Engine registration: '{engine_name}'."
                )

            names.add(engine_name)