"""Execution-contract shared value types.

These models are acceptance-only schema definitions for the execution-kernel
boundary. They define immutable resolved-truth sections and structured
spawnability metadata without introducing orchestration behavior.
"""

from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, ConfigDict, Field

from anima.core.schemas.enums import SideEffectPolicy

EXECUTION_INTENT_VERSION = "0.1.0"
CONTRACT_SCHEMA_VERSION = "0.1.0"
EXECUTION_SESSION_VERSION = "0.1.0"

ResolverVersion = str
RuntimeToolName = str
RuntimeToolPreset = str
AgentStateSnapshotRef = str
FilesystemScope = str
SessionAttachMode = Literal["detached", "interactive", "monitor", "streaming"]
PersonaSource = Literal["file", "inline", "synthesized", "snapshot"]
MaterializedPersonaStatus = Literal[
    "not_required",
    "materialized",
    "pending_materialization",
    "not_materialized",
]
InlinePersonaBehavior = Literal["auto_materialize_snapshot", "reject_spawn"]
ChildInheritancePolicy = Literal[
    "inherit_reusable_persona_ref",
    "inherit_materialized_snapshot",
    "require_explicit_child_persona",
    "reject_child_inheritance",
]
SpawnabilityReasonCode = Literal[
    "spawnable",
    "missing_reusable_persona_ref",
    "inline_persona_requires_materialization",
    "synthesized_persona_requires_materialization",
    "child_inheritance_disabled",
    "contract_resolution_incomplete",
]


class ContractSourceHashes(BaseModel):
    """Identity hashes for the inputs used during contract resolution."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    persona_digest: str | None = None
    job_digest: str | None = None
    cli_digest: str | None = None
    defaults_digest: str | None = None


class ContractResolverProvenance(BaseModel):
    """Versioned provenance for the resolver that produced effective truth."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    resolver_version: ResolverVersion = Field(min_length=1)
    intent_version: Literal["0.1.0"] = EXECUTION_INTENT_VERSION
    source_hashes: ContractSourceHashes = Field(default_factory=ContractSourceHashes)


class ContractIdentity(BaseModel):
    """Stable identity for an immutable resolved execution contract."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    instance_id: str = Field(min_length=1)
    contract_version: Literal["0.1.0"] = CONTRACT_SCHEMA_VERSION
    resolver: ContractResolverProvenance


class RuntimeToolAccess(BaseModel):
    """Declared, requested, and effective tool access for one execution."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    declared_persona_tools: tuple[RuntimeToolName, ...] = ()
    requested_cli_tools: tuple[RuntimeToolName, ...] = ()
    requested_mcp_tools: tuple[RuntimeToolName, ...] = ()
    effective_tools: tuple[RuntimeToolName, ...] = ()
    effective_presets: tuple[RuntimeToolPreset, ...] = ()
    effective_side_effect_policy: SideEffectPolicy


class SpawnabilityReason(BaseModel):
    """Structured user-facing explanation for child-agent spawnability."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    code: SpawnabilityReasonCode
    message: str = Field(min_length=1)
    user_action: str | None = None
    retryable: bool = False
    details: dict[str, str] = Field(default_factory=dict)


class PersonaSpawnability(BaseModel):
    """Resolved child-agent spawnability derived from persona provenance truth."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    can_spawn: bool
    reason: SpawnabilityReason | None = None


class PersonaProvenance(BaseModel):
    """Resolved provenance and inheritance posture for the effective persona."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    source: PersonaSource
    reusable_persona_ref: str | None = None
    materialization_status: MaterializedPersonaStatus
    inline_behavior: InlinePersonaBehavior
    child_inheritance_policy: ChildInheritancePolicy
    spawnability: PersonaSpawnability


class RuntimeOutputPolicy(BaseModel):
    """Resolved output-governance values surfaced to runtime consumers."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    provider_profile: str = Field(min_length=1)
    per_call_tool_output_chars: int | None = None
    per_turn_tool_output_chars: int | None = None
    truncation_strategy: str = Field(min_length=1)


class RuntimeModelContext(BaseModel):
    """Runtime facts safe to inject into prompts and model-visible context."""

    model_config = ConfigDict(extra="forbid", frozen=True)

    values: dict[str, str | int | float | bool | None] = Field(default_factory=dict)


class SessionTransportState(BaseModel):
    """Ephemeral attach and transport status for one live execution session."""

    model_config = ConfigDict(extra="forbid")

    attach_mode: SessionAttachMode | None = None
    stream_active: bool = False
    transport_connected: bool = False
    socket_path: str | None = None
    pending_approval_prompt: bool = False
    terminal_snapshot_ref: AgentStateSnapshotRef | None = None
    last_seen_at: str | None = None
