"""Data models for the eval framework."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any

from hatchdx import HdxError


class EvalError(HdxError):
    """Raised when an eval operation fails."""


@dataclass
class EvalAssertion:
    """A single assertion to evaluate against a tool response."""

    type: str  # "schema", "range", "length", "contains", "golden_file"
    path: str | None = None  # JSONPath expression (for range, length, contains)
    schema: dict[str, Any] | None = None  # JSON Schema (for schema type)
    min: float | None = None  # For range
    max: float | None = None  # For range
    expected: Any | None = None  # For length, contains
    golden_file: str | None = None  # Path to golden file


VALID_ASSERTION_TYPES = {"schema", "range", "length", "contains", "golden_file"}


@dataclass
class EvalCase:
    """A single eval case — call a tool and check assertions against the response."""

    name: str
    tool: str
    input: dict[str, Any]
    assertions: list[EvalAssertion]


@dataclass
class EvalSuite:
    """A collection of eval cases loaded from a YAML file."""

    name: str
    description: str
    evals: list[EvalCase]


@dataclass
class AssertionOutcome:
    """The result of evaluating a single assertion."""

    assertion: EvalAssertion
    passed: bool
    reason: str


@dataclass
class EvalResult:
    """The outcome of running a single eval case."""

    eval_case: EvalCase
    passed: bool
    assertion_results: list[AssertionOutcome]
    latency_ms: float
    timestamp: datetime = field(default_factory=datetime.now)
    error: str | None = None  # Set when the tool call itself failed
