"""
Reasoner configuration models.

This module defines reasoner-specific configuration:
- Engine size type aliases (Internal, AWS, Azure)
- ReasonerConfig: Configuration for a single reasoner instance
- ReasonersConfig: Configuration for all reasoner types (logic, predictive, prescriptive)
"""

from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, ConfigDict, Field


# Engine size type aliases
# Internal development sizes
InternalEngineSize = Literal["XS", "S", "M", "L"]

# AWS Snowflake sizes
AWSEngineSize = Literal["HIGHMEM_X64_S", "HIGHMEM_X64_M", "HIGHMEM_X64_L"]

# Azure sizes
AzureEngineSize = Literal["HIGHMEM_X64_S", "HIGHMEM_X64_M", "HIGHMEM_X64_SL"]

# All valid engine sizes across platforms
EngineSize = InternalEngineSize | AWSEngineSize | AzureEngineSize

# LQP Semantics Version
# When the logic engine introduces breaking changes, this version is bumped
# [2026-01-09] Version "1" opts into hard validation errors from the engine
LqpSemanticsVersion = Literal["1"]


class ReasonerLogicLqpConfig(BaseModel):
    """LQP-specific configuration for logic reasoner."""

    semantics_version: LqpSemanticsVersion | None = Field(
        default=None,
        description="LQP semantics version for breaking changes (e.g., '1' for hard validation errors)"
    )


class ReasonerConfig(BaseModel):
    """Configuration for a single reasoner instance."""

    model_config = ConfigDict(extra="allow")

    name: str | None = Field(
        default=None,
        description="Optional name for the reasoner instance"
    )

    size: EngineSize = Field(
        default="HIGHMEM_X64_S",
        description="Compute size (e.g., 'HIGHMEM_X64_S', 'HIGHMEM_X64_M')",
        examples=["HIGHMEM_X64_S", "HIGHMEM_X64_M", "HIGHMEM_X64_L"]
    )

    query_timeout_mins: int | None = Field(
        default=None,
        description="Query timeout in minutes - aborts queries that exceed this duration"
    )

    auto_suspend_mins: int = Field(
        default=60,
        description="Auto-suspend reasoner after N minutes of inactivity"
    )


class LogicReasonerConfig(ReasonerConfig):
    """Configuration for logic reasoner with rule execution settings."""

    use_lqp: bool = Field(
        default=True,
        description="Use LQP for reasoner rule execution"
    )

    incremental_maintenance: str | None = Field(
        default="auto",
        description="Incremental maintenance strategy"
    )

    emit_constraints: bool = Field(
        default=False,
        description="Emit constraints during execution"
    )

    lqp: ReasonerLogicLqpConfig = Field(
        default_factory=ReasonerLogicLqpConfig,
        description="LQP-specific configuration"
    )


class ReasonersConfig(BaseModel):
    """Configuration for all reasoners. Each type can have only one reasoner."""

    logic: LogicReasonerConfig = Field(
        default_factory=LogicReasonerConfig,
        description="Logic reasoner configuration"
    )

    predictive: ReasonerConfig | None = Field(
        default=None,
        description="Predictive reasoner configuration"
    )

    prescriptive: ReasonerConfig | None = Field(
        default=None,
        description="Prescriptive reasoner configuration"
    )
