"""Tests for JSON schema generation from Pydantic models."""

from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, Field

from koan.output.schema import pydantic_to_json_schema


class TestPydanticToJsonSchema:
    def test_basic_model(self) -> None:
        class Answer(BaseModel):
            text: str
            score: float

        result = pydantic_to_json_schema(Answer)
        assert result["type"] == "json_schema"
        assert result["json_schema"]["name"] == "Answer"
        schema = result["json_schema"]["schema"]
        assert "text" in schema["properties"]
        assert "score" in schema["properties"]

    def test_custom_name(self) -> None:
        class Foo(BaseModel):
            x: int

        result = pydantic_to_json_schema(Foo, name="CustomName")
        assert result["json_schema"]["name"] == "CustomName"

    def test_field_descriptions(self) -> None:
        class Described(BaseModel):
            query: str = Field(description="Search query")

        result = pydantic_to_json_schema(Described)
        props = result["json_schema"]["schema"]["properties"]
        assert props["query"]["description"] == "Search query"

    def test_literal_type(self) -> None:
        class WithLiteral(BaseModel):
            mood: Literal["happy", "sad", "neutral"]

        result = pydantic_to_json_schema(WithLiteral)
        props = result["json_schema"]["schema"]["properties"]
        assert "enum" in props["mood"]
        assert set(props["mood"]["enum"]) == {"happy", "sad", "neutral"}

    def test_nested_model(self) -> None:
        class Inner(BaseModel):
            value: int

        class Outer(BaseModel):
            items: list[Inner]

        result = pydantic_to_json_schema(Outer)
        schema = result["json_schema"]["schema"]
        assert "items" in schema["properties"]
