"""Semantic Escalation domain models.

Defines the ``EscalationDecision``, ``OperationContext``, and
``ConfidenceFactors`` models used by the Semantic Escalation system
to decide whether an operation should proceed automatically or
escalate to the user for approval.

The confidence score (0.0--1.0) is compared against the active
automation profile's threshold for the relevant flag.  When the
score meets or exceeds the threshold the operation proceeds
autonomously; otherwise the user is prompted.

Based on ``docs/specification.md`` Section "Semantic Escalation"
(lines 28176--28206).
"""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field, field_validator


class ConfidenceFactors(BaseModel):
    """Individual factors contributing to the confidence score.

    Each factor is a float in [0.0, 1.0].

    Attributes:
        past_success_rate: Historical success rate for similar ops.
        codebase_familiarity: Agent knowledge of relevant code area.
        risk_assessment: Estimated risk (0.0 = no risk, 1.0 = max).
        invariant_complexity: Complexity of invariants to preserve
            (0.0 = trivial, 1.0 = extremely complex).
    """

    past_success_rate: float = Field(
        0.5,
        ge=0.0,
        le=1.0,
        description="Historical success rate for similar operations",
    )
    codebase_familiarity: float = Field(
        0.5,
        ge=0.0,
        le=1.0,
        description="Agent familiarity with relevant code area",
    )
    risk_assessment: float = Field(
        0.5,
        ge=0.0,
        le=1.0,
        description=(
            "Estimated risk of the operation (0.0 = no risk, 1.0 = maximum risk)"
        ),
    )
    invariant_complexity: float = Field(
        0.5,
        ge=0.0,
        le=1.0,
        description=(
            "Complexity of invariants that must be preserved "
            "(0.0 = trivial, 1.0 = extremely complex)"
        ),
    )

    @field_validator(
        "past_success_rate",
        "codebase_familiarity",
        "risk_assessment",
        "invariant_complexity",
    )
    @classmethod
    def validate_factor_range(
        cls: type[ConfidenceFactors],
        v: float,
    ) -> float:
        """Validate factor is in [0.0, 1.0]."""
        if v < 0.0 or v > 1.0:
            raise ValueError(f"Factor must be between 0.0 and 1.0, got {v}")
        return v

    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
    )


class OperationContext(BaseModel):
    """Context for an operation being evaluated for escalation.

    Attributes:
        operation_type: Type/name of the operation (e.g. the
            automation profile flag like ``create_tool``).
        project_id: Identifier of the project being operated on.
        file_count: Number of files affected by the operation.
        test_coverage: Test coverage ratio for affected code.
        blast_radius: Estimated blast radius (0.0--1.0).
    """

    operation_type: str = Field(
        ...,
        min_length=1,
        description="Automation profile flag name (e.g. 'create_tool')",
    )
    project_id: str = Field(
        default="",
        description="Identifier of the project being operated on",
    )
    file_count: int = Field(
        default=0,
        ge=0,
        description="Number of files affected by the operation",
    )
    test_coverage: float = Field(
        default=0.5,
        ge=0.0,
        le=1.0,
        description="Test coverage ratio for affected code area",
    )
    blast_radius: float = Field(
        default=0.5,
        ge=0.0,
        le=1.0,
        description="Estimated blast radius (0.0 = none, 1.0 = full)",
    )

    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
    )


class EscalationDecision(BaseModel):
    """Result of a semantic escalation check.

    Returned by ``AutonomyController.should_proceed_automatically()``.

    Attributes:
        proceed: Whether the operation should proceed automatically.
        confidence: Computed confidence score (0.0--1.0).
        factors: Individual factor values that produced the score.
        explanation: Human-readable explanation of the decision.
        threshold: The automation profile threshold that was compared.
        operation_type: The operation type that was evaluated.
    """

    proceed: bool = Field(
        ...,
        description="Whether to proceed automatically",
    )
    confidence: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Computed confidence score (0.0--1.0)",
    )
    factors: dict[str, float] = Field(
        ...,
        description="Individual factor values used in computation",
    )
    explanation: str = Field(
        ...,
        min_length=1,
        description="Human-readable explanation of the decision",
    )
    threshold: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Automation profile threshold used for comparison",
    )
    operation_type: str = Field(
        ...,
        min_length=1,
        description="The operation type that was evaluated",
    )

    model_config = ConfigDict(
        str_strip_whitespace=True,
    )


class HistoricalOutcome(BaseModel):
    """A single recorded outcome of an autonomous decision.

    Attributes:
        operation_type: The operation type that was performed.
        succeeded: Whether the autonomous operation succeeded.
    """

    operation_type: str = Field(
        ...,
        min_length=1,
        description="The operation type that was performed",
    )
    succeeded: bool = Field(
        ...,
        description="Whether the autonomous operation succeeded",
    )

    model_config = ConfigDict(
        str_strip_whitespace=True,
    )
