# tests/models/syndarix/conftest.py
"""
Shared fixtures for Syndarix model tests.
"""

import uuid
from datetime import date, timedelta

import pytest
import pytest_asyncio

from app.models.syndarix import (
    AgentInstance,
    AgentStatus,
    AgentType,
    AutonomyLevel,
    Issue,
    IssuePriority,
    IssueStatus,
    Project,
    ProjectStatus,
    Sprint,
    SprintStatus,
)
from app.models.user import User


@pytest.fixture
def sample_project_data():
    """Return sample project data for testing."""
    return {
        "name": "Test Project",
        "slug": "test-project",
        "description": "A test project for unit testing",
        "autonomy_level": AutonomyLevel.MILESTONE,
        "status": ProjectStatus.ACTIVE,
        "settings": {"mcp_servers": ["gitea", "slack"]},
    }


@pytest.fixture
def sample_agent_type_data():
    """Return sample agent type data for testing."""
    return {
        "name": "Backend Engineer",
        "slug": "backend-engineer",
        "description": "Specialized in backend development",
        "expertise": ["python", "fastapi", "postgresql"],
        "personality_prompt": "You are an expert backend engineer...",
        "primary_model": "claude-opus-4-5-20251101",
        "fallback_models": ["claude-sonnet-4-20250514"],
        "model_params": {"temperature": 0.7, "max_tokens": 4096},
        "mcp_servers": ["gitea", "file-system"],
        "tool_permissions": {"allowed": ["*"], "denied": []},
        "is_active": True,
    }


@pytest.fixture
def sample_sprint_data():
    """Return sample sprint data for testing."""
    today = date.today()
    return {
        "name": "Sprint 1",
        "number": 1,
        "goal": "Complete initial setup and core features",
        "start_date": today,
        "end_date": today + timedelta(days=14),
        "status": SprintStatus.PLANNED,
        "planned_points": 21,
        "completed_points": 0,
    }


@pytest.fixture
def sample_issue_data():
    """Return sample issue data for testing."""
    return {
        "title": "Implement user authentication",
        "body": "As a user, I want to log in securely...",
        "status": IssueStatus.OPEN,
        "priority": IssuePriority.HIGH,
        "labels": ["backend", "security"],
        "story_points": 5,
    }


@pytest_asyncio.fixture
async def test_owner(async_test_db):
    """Create a test user to be used as project owner."""
    from app.core.auth import get_password_hash

    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        user = User(
            id=uuid.uuid4(),
            email="owner@example.com",
            password_hash=get_password_hash("TestPassword123!"),
            first_name="Test",
            last_name="Owner",
            is_active=True,
            is_superuser=False,
        )
        session.add(user)
        await session.commit()
        await session.refresh(user)
        return user


@pytest_asyncio.fixture
async def test_project(async_test_db, test_owner, sample_project_data):
    """Create a test project in the database."""
    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        project = Project(
            id=uuid.uuid4(),
            owner_id=test_owner.id,
            **sample_project_data,
        )
        session.add(project)
        await session.commit()
        await session.refresh(project)
        return project


@pytest_asyncio.fixture
async def test_agent_type(async_test_db, sample_agent_type_data):
    """Create a test agent type in the database."""
    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        agent_type = AgentType(
            id=uuid.uuid4(),
            **sample_agent_type_data,
        )
        session.add(agent_type)
        await session.commit()
        await session.refresh(agent_type)
        return agent_type


@pytest_asyncio.fixture
async def test_agent_instance(async_test_db, test_project, test_agent_type):
    """Create a test agent instance in the database."""
    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        agent_instance = AgentInstance(
            id=uuid.uuid4(),
            agent_type_id=test_agent_type.id,
            project_id=test_project.id,
            status=AgentStatus.IDLE,
            current_task=None,
            short_term_memory={},
            long_term_memory_ref=None,
            session_id=None,
        )
        session.add(agent_instance)
        await session.commit()
        await session.refresh(agent_instance)
        return agent_instance


@pytest_asyncio.fixture
async def test_sprint(async_test_db, test_project, sample_sprint_data):
    """Create a test sprint in the database."""
    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        sprint = Sprint(
            id=uuid.uuid4(),
            project_id=test_project.id,
            **sample_sprint_data,
        )
        session.add(sprint)
        await session.commit()
        await session.refresh(sprint)
        return sprint


@pytest_asyncio.fixture
async def test_issue(async_test_db, test_project, sample_issue_data):
    """Create a test issue in the database."""
    _test_engine, AsyncTestingSessionLocal = async_test_db
    async with AsyncTestingSessionLocal() as session:
        issue = Issue(
            id=uuid.uuid4(),
            project_id=test_project.id,
            **sample_issue_data,
        )
        session.add(issue)
        await session.commit()
        await session.refresh(issue)
        return issue
