"""Tests for Pydantic data models."""

from datetime import datetime

from src.models import AgentConfig, MeetingState, PMDecision, ScratchpadEntry


class TestAgentConfig:
    """Tests for AgentConfig model."""

    def test_create_minimal_agent_config(self) -> None:
        """AgentConfig requires name, role, system_prompt."""
        config = AgentConfig(
            name="test_agent",
            role="Tester",
            system_prompt="You are a tester.",
        )
        assert config.name == "test_agent"
        assert config.role == "Tester"
        assert config.system_prompt == "You are a tester."
        assert config.input_schema == ""
        assert config.output_schema == ""

    def test_create_full_agent_config(self) -> None:
        """AgentConfig with all fields populated."""
        config = AgentConfig(
            name="full_agent",
            role="Full Role",
            system_prompt="Full prompt.",
            input_schema="expects a question string",
            output_schema="returns analysis string",
        )
        assert config.input_schema == "expects a question string"
        assert config.output_schema == "returns analysis string"

    def test_agent_config_serialization(self) -> None:
        """AgentConfig round-trips through JSON."""
        config = AgentConfig(
            name="test",
            role="Role",
            system_prompt="Prompt.",
        )
        data = config.model_dump()
        restored = AgentConfig(**data)
        assert restored == config


class TestScratchpadEntry:
    """Tests for ScratchpadEntry model."""

    def test_create_scratchpad_entry(self) -> None:
        """ScratchpadEntry stores agent name, content, timestamp."""
        now = datetime(2026, 3, 30, 10, 0, 0)
        entry = ScratchpadEntry(
            agent_name="architect",
            content="We should use microservices.",
            timestamp=now,
        )
        assert entry.agent_name == "architect"
        assert entry.content == "We should use microservices."
        assert entry.timestamp == now


class TestMeetingState:
    """Tests for MeetingState model."""

    def test_create_default_meeting_state(self) -> None:
        """MeetingState with defaults has empty scratchpad and round 0."""
        state = MeetingState(topic="Test topic")
        assert state.topic == "Test topic"
        assert state.scratchpad == []
        assert state.current_round == 0
        assert state.max_rounds == 5

    def test_meeting_state_with_entries(self) -> None:
        """MeetingState can hold scratchpad entries."""
        entry = ScratchpadEntry(
            agent_name="test",
            content="Hello",
            timestamp=datetime(2026, 3, 30, 10, 0, 0),
        )
        state = MeetingState(topic="Topic", scratchpad=[entry])
        assert len(state.scratchpad) == 1
        assert state.scratchpad[0].agent_name == "test"


import pytest
from pydantic import ValidationError


class TestPMDecision:
    """Tests for PMDecision model with conditional validation."""

    def test_call_agent_decision(self) -> None:
        """CALL_AGENT requires target_agent and prompt_for_agent."""
        decision = PMDecision(
            analysis="Need architect input.",
            next_action="CALL_AGENT",
            target_agent="architect",
            prompt_for_agent="What about scalability?",
        )
        assert decision.next_action == "CALL_AGENT"
        assert decision.target_agent == "architect"

    def test_finish_decision(self) -> None:
        """FINISH requires final_report."""
        decision = PMDecision(
            analysis="All topics covered.",
            next_action="FINISH",
            final_report="# Meeting Report\n\nDone.",
        )
        assert decision.next_action == "FINISH"
        assert decision.final_report is not None

    def test_call_agent_missing_target_raises(self) -> None:
        """CALL_AGENT without target_agent raises ValidationError."""
        with pytest.raises(ValidationError, match="target_agent"):
            PMDecision(
                analysis="Need input.",
                next_action="CALL_AGENT",
                prompt_for_agent="Question?",
            )

    def test_call_agent_missing_prompt_raises(self) -> None:
        """CALL_AGENT without prompt_for_agent raises ValidationError."""
        with pytest.raises(ValidationError, match="prompt_for_agent"):
            PMDecision(
                analysis="Need input.",
                next_action="CALL_AGENT",
                target_agent="architect",
            )

    def test_finish_missing_report_raises(self) -> None:
        """FINISH without final_report raises ValidationError."""
        with pytest.raises(ValidationError, match="final_report"):
            PMDecision(
                analysis="Done.",
                next_action="FINISH",
            )

    def test_invalid_next_action_raises(self) -> None:
        """Invalid next_action value raises ValidationError."""
        with pytest.raises(ValidationError):
            PMDecision(
                analysis="Hmm.",
                next_action="INVALID",
            )
