"""Pydantic models for validation suites, cases, expectations, and results."""

from pydantic import BaseModel, Field

# ---------------------------------------------------------------------------
# Suite definition (loaded from YAML)
# ---------------------------------------------------------------------------


class IngestSetup(BaseModel):
    """Document ingestion to run before test cases."""

    path: str
    collection: str = "validation"
    chunk_size: int = 512
    chunk_overlap: int = 64


class SuiteSetup(BaseModel):
    """Setup block — runs before any cases."""

    ingest: list[IngestSetup] = Field(default_factory=list)


class SuiteTeardown(BaseModel):
    """Teardown block — runs after all cases."""

    cleanup_collections: list[str] = Field(default_factory=list)


class CaseExpectation(BaseModel):
    """Assertions for a single test case.

    All checks are case-insensitive substring matches unless noted.
    """

    # Tool assertions
    tools_used: list[str] = Field(
        default_factory=list,
        description="Tool names that MUST appear in the tool call log.",
    )
    min_tool_calls: int = Field(
        default=0,
        description="Minimum total number of tool invocations.",
    )

    # Response content assertions
    response_contains: list[str] = Field(
        default_factory=list,
        description="Substrings that MUST ALL appear in the response (case-insensitive).",
    )
    response_not_contains: list[str] = Field(
        default_factory=list,
        description="Substrings that MUST NOT appear in the response (case-insensitive).",
    )
    response_contains_any: list[str] = Field(
        default_factory=list,
        description="At least ONE of these substrings must appear (case-insensitive).",
    )

    # Execution assertions
    max_steps: int | None = Field(
        default=None,
        description="Maximum steps the turn should take.",
    )
    success: bool = Field(
        default=True,
        description="Whether the turn should succeed.",
    )


class ValidationCase(BaseModel):
    """A single test case in a validation suite."""

    id: str
    input: str
    description: str = ""
    expect: CaseExpectation = Field(default_factory=CaseExpectation)

    # Optional per-case overrides
    agent: str | None = None
    pathway: str | None = None


class ValidationSuite(BaseModel):
    """A complete validation suite loaded from YAML."""

    id: str
    name: str = ""
    description: str = ""

    # Defaults for all cases
    agent: str = "host"
    pathway: str | None = None

    setup: SuiteSetup = Field(default_factory=SuiteSetup)
    cases: list[ValidationCase] = Field(default_factory=list)
    teardown: SuiteTeardown = Field(default_factory=SuiteTeardown)


# ---------------------------------------------------------------------------
# Results (produced by the runner)
# ---------------------------------------------------------------------------


class AssertionFailure(BaseModel):
    """A single failed assertion within a case."""

    check: str
    expected: str
    actual: str


class CaseResult(BaseModel):
    """Result of running a single validation case."""

    case_id: str
    passed: bool
    response: str = ""
    tools_called: list[str] = Field(default_factory=list)
    tool_call_count: int = 0
    steps_taken: int = 0
    duration_ms: int = 0
    tokens_used: int = 0
    cost_usd: float = 0.0
    failures: list[AssertionFailure] = Field(default_factory=list)
    error: str | None = None


class ValidationResult(BaseModel):
    """Aggregate result of a full validation suite run."""

    suite_id: str
    suite_name: str = ""
    passed: bool
    cases_run: int = 0
    cases_passed: int = 0
    cases_failed: int = 0
    total_duration_ms: int = 0
    results: list[CaseResult] = Field(default_factory=list)
    setup_error: str | None = None
