"""Tests for SchemaCheck."""

from __future__ import annotations

import pytest

from ai_qa.checks.schema import SchemaCheck
from ai_qa.core.context import Context


def test_schema_check_requires_schema():
    """Test that SchemaCheck requires schema parameter."""
    with pytest.raises(ValueError) as exc_info:
        SchemaCheck()
    assert "schema" in str(exc_info.value)


def test_schema_check_valid_dict_output():
    """Test SchemaCheck with valid dict output."""
    schema = {
        "type": "object",
        "properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
        "required": ["name"],
    }
    check = SchemaCheck(schema=schema)
    ctx = Context(output={"name": "John", "age": 30})
    result = check.evaluate(ctx)
    assert result.passed is True
    assert result.score == 1.0


def test_schema_check_invalid_dict_output():
    """Test SchemaCheck with invalid dict output."""
    schema = {
        "type": "object",
        "properties": {"name": {"type": "string"}},
        "required": ["name"],
    }
    check = SchemaCheck(schema=schema)
    ctx = Context(output={"age": 30})  # Missing required 'name'
    result = check.evaluate(ctx)
    assert result.passed is False
    assert result.score == 0.0
    assert "required property" in result.evidence.lower()


def test_schema_check_json_string_input():
    """Test SchemaCheck with JSON string input."""
    schema = {"type": "object", "properties": {"value": {"type": "integer"}}}
    check = SchemaCheck(schema=schema)
    ctx = Context(output='{"value": 42}')
    result = check.evaluate(ctx)
    assert result.passed is True
    assert result.score == 1.0


def test_schema_check_invalid_json_string():
    """Test SchemaCheck with invalid JSON string."""
    schema = {"type": "object"}
    check = SchemaCheck(schema=schema)
    ctx = Context(output='{"invalid": json}')
    result = check.evaluate(ctx)
    assert result.passed is False
    assert result.score == 0.0
    assert "not valid JSON" in result.evidence


def test_schema_check_list_output():
    """Test SchemaCheck with list output."""
    schema = {"type": "array", "items": {"type": "string"}}
    check = SchemaCheck(schema=schema)
    ctx = Context(output=["a", "b", "c"])
    result = check.evaluate(ctx)
    assert result.passed is True


def test_schema_check_invalid_list_output():
    """Test SchemaCheck with invalid list output."""
    schema = {"type": "array", "items": {"type": "integer"}}
    check = SchemaCheck(schema=schema)
    ctx = Context(output=[1, "two", 3])  # "two" is not an integer
    result = check.evaluate(ctx)
    assert result.passed is False


def test_schema_check_type_validation():
    """Test SchemaCheck validates type correctly."""
    schema = {"type": "string"}
    check = SchemaCheck(schema=schema)
    ctx = Context(output={"key": "value"})  # Dict, not string
    result = check.evaluate(ctx)
    assert result.passed is False
    assert "string" in result.evidence.lower()


def test_schema_check_complex_schema():
    """Test SchemaCheck with complex nested schema."""
    schema = {
        "type": "object",
        "properties": {
            "user": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "emails": {"type": "array", "items": {"type": "string"}},
                },
                "required": ["name"],
            }
        },
        "required": ["user"],
    }
    check = SchemaCheck(schema=schema)
    valid_ctx = Context(
        output={"user": {"name": "Alice", "emails": ["alice@example.com"]}}
    )
    result = check.evaluate(valid_ctx)
    assert result.passed is True

    invalid_ctx = Context(output={"user": {"emails": ["alice@example.com"]}})
    result = check.evaluate(invalid_ctx)
    assert result.passed is False


def test_schema_check_custom_threshold():
    """Test SchemaCheck with custom threshold."""
    schema = {"type": "object"}
    check = SchemaCheck(schema=schema, threshold=0.8)
    assert check.threshold == 0.8


def test_schema_check_version():
    """Test SchemaCheck has correct version."""
    check = SchemaCheck(schema={"type": "object"})
    assert check.version == "1.0.0"


def test_schema_check_name():
    """Test SchemaCheck has correct name."""
    check = SchemaCheck(schema={"type": "object"})
    assert check.name == "schema"


def test_schema_check_requires_llm():
    """Test SchemaCheck does not require LLM."""
    check = SchemaCheck(schema={"type": "object"})
    assert check.requires_llm is False
