"""Unit tests for Issue #24: ScriptBased_Agent_Support_Issue_24_ADR001_ADR002_ADR003.

This file contains unit tests that validate implementation details derived from
BDD scenarios. These tests focus on individual functions, methods, and components
rather than end-to-end behavior.

Generated by: BDD Unit Test Generator
BDD Source: issue-24-script-agents.feature
"""

import json

import pytest
from pydantic import ValidationError

from llm_orc.schemas.script_agent import ScriptAgentInput, ScriptAgentOutput


class TestIssue24Units:
    """Unit tests derived from BDD scenarios."""

    def test_validate_input(self) -> None:
        """Test validation of input based on BDD scenario.

        BDD Context:     And it should validate input using Pydantic schemas
        """
        # Test valid input validation
        valid_input = {
            "agent_name": "test_agent",
            "input_data": "test input",
            "context": {"key": "value"},
            "dependencies": {"dep1": "value1"},
        }

        # Should not raise exception
        validated = ScriptAgentInput.model_validate(valid_input)
        assert validated.agent_name == "test_agent"
        assert validated.input_data == "test input"
        assert validated.context == {"key": "value"}
        assert validated.dependencies == {"dep1": "value1"}

    def test_schema_validation(self) -> None:
        """Test Pydantic schema validation logic."""
        # Test missing required field
        with pytest.raises(ValidationError) as exc_info:
            ScriptAgentInput.model_validate({"input_data": "test"})

        assert "agent_name" in str(exc_info.value)

        # Test invalid types
        with pytest.raises(ValidationError):
            ScriptAgentInput.model_validate(
                {
                    "agent_name": 123,  # Should be string
                    "input_data": "test",
                }
            )

    def test_json_serialization(self) -> None:
        """Test JSON serialization/deserialization."""
        # Test valid JSON output structure
        output_data = {
            "success": True,
            "data": {"result": "test_result"},
            "error": None,
            "agent_requests": [],
        }

        # Should serialize/deserialize correctly
        json_str = json.dumps(output_data)
        parsed = json.loads(json_str)

        # Validate against schema
        validated = ScriptAgentOutput.model_validate(parsed)
        assert validated.success is True
        assert validated.data == {"result": "test_result"}
        assert validated.error is None
        assert validated.agent_requests == []

    def test_caching_behavior(self) -> None:
        """Test caching mechanism."""
        # Test identical inputs produce consistent outputs
        input1 = ScriptAgentInput(agent_name="cache_test", input_data="identical_input")
        input2 = ScriptAgentInput(agent_name="cache_test", input_data="identical_input")

        # Should be equivalent for caching purposes
        assert input1.model_dump() == input2.model_dump()

        # Test different inputs are distinguished
        input3 = ScriptAgentInput(agent_name="cache_test", input_data="different_input")
        assert input1.model_dump() != input3.model_dump()

    def test_error_handling(self) -> None:
        """Test error handling and exception chaining."""
        # Test error output structure
        error_output = ScriptAgentOutput(
            success=False, data=None, error="Script failed with exit code 1"
        )

        assert error_output.success is False
        assert error_output.data is None
        assert error_output.error is not None
        assert "exit code 1" in error_output.error

        # Test validation of error states
        with pytest.raises(ValidationError):
            ScriptAgentOutput(success="invalid")  # type: ignore  # Should be boolean
