import pytest
import uuid
# --- MODIFIED: Import ValidationError from pydantic_core ---
import pydantic
from pydantic_core import ValidationError
# --- END MODIFIED ---
from typing import Dict, Any

# Import the factory function and models (with fallback)
from agentvault_testing_utils.factories import create_test_agent_card
try:
    from agentvault.models import AgentCard, AgentProvider, AgentAuthentication
    _MODELS_AVAILABLE = True
except ImportError:
    AgentCard = None # type: ignore
    AgentProvider = None # type: ignore
    AgentAuthentication = None # type: ignore
    _MODELS_AVAILABLE = False

# Skip tests if models aren't available
pytestmark = pytest.mark.skipif(not _MODELS_AVAILABLE, reason="Core agentvault models not available for factory tests")


def test_create_test_agent_card_defaults():
    """Test creating an agent card with default values."""
    card = create_test_agent_card()

    assert isinstance(card, AgentCard)
    assert card.schema_version == "1.0"
    assert card.name == "Factory Test Agent"
    assert card.agent_version == "0.1.0-test"
    assert card.human_readable_id.startswith("test-org/factory-agent-")
    assert card.provider.name == "Factory Provider Inc."
    assert card.capabilities.a2a_version == "1.0"
    assert card.auth_schemes[0].scheme == "none"
    assert card.tags == ["test", "factory-generated"]

def test_create_test_agent_card_override_simple():
    """Test overriding simple top-level fields."""
    override_name = "My Custom Agent"
    override_version = "2.0.0"
    override_id = "my-org/my-agent"

    card = create_test_agent_card(
        name=override_name,
        agentVersion=override_version, # Use alias if model uses it
        humanReadableId=override_id
    )

    assert isinstance(card, AgentCard)
    assert card.name == override_name
    assert card.agent_version == override_version
    assert card.human_readable_id == override_id
    # Check a default field is still there
    assert card.description == "An agent generated by the test factory."

def test_create_test_agent_card_override_nested_dict():
    """Test overriding fields within a nested dictionary (provider)."""
    override_provider_name = "My Company"
    override_provider_url = "https://my-company.com" # No trailing slash in input

    card = create_test_agent_card(
        provider={"name": override_provider_name, "url": override_provider_url}
    )

    assert isinstance(card, AgentCard)
    assert isinstance(card.provider, AgentProvider)
    assert card.provider.name == override_provider_name
    assert str(card.provider.url).rstrip('/') == override_provider_url.rstrip('/')
    assert card.provider.support_contact is None

def test_create_test_agent_card_override_list():
    """Test overriding a list field (authSchemes)."""
    override_auth = [
        {"scheme": "apiKey", "service_identifier": "my-key-id"}
    ]
    card = create_test_agent_card(authSchemes=override_auth) # Use alias

    assert isinstance(card, AgentCard)
    assert len(card.auth_schemes) == 1
    assert isinstance(card.auth_schemes[0], AgentAuthentication)
    assert card.auth_schemes[0].scheme == "apiKey"
    assert card.auth_schemes[0].service_identifier == "my-key-id"

def test_create_test_agent_card_override_nested_partial():
    """Test partially overriding a nested dictionary."""
    card = create_test_agent_card(provider={"name": "Partial Provider"})

    assert isinstance(card, AgentCard)
    assert card.provider.name == "Partial Provider"
    assert card.provider.url is None # Check default was preserved

def test_create_test_agent_card_invalid_override_type():
    """Test that validation still occurs with overrides (e.g., wrong type)."""
    # --- MODIFIED: Catch ValidationError from pydantic_core ---
    with pytest.raises(ValidationError):
        create_test_agent_card(provider="not a dict")

    with pytest.raises(ValidationError):
        create_test_agent_card(authSchemes=[{"scheme": "invalid"}])
    # --- END MODIFIED ---
