"""
tests/conftest.py

Configuration for pytest.
"""

from pathlib import Path
from typing import Any
from unittest.mock import MagicMock, patch

import pytest

from bluebox.data_models.routine.routine import Routine
from bluebox.data_models.routine.operation import RoutineOperationUnion


@pytest.fixture(autouse=True)
def mock_openai_clients() -> dict[str, MagicMock]:
    """
    Mock OpenAI clients to avoid needing real API keys in tests.

    This fixture automatically patches the OpenAI and AsyncOpenAI classes
    wherever they're imported in the openai_client module, so tests can
    instantiate OpenAIClient without a valid API key.
    """
    with (
        patch("bluebox.llms.openai_client.OpenAI") as mock_openai,
        patch("bluebox.llms.openai_client.AsyncOpenAI") as mock_async_openai,
    ):
        mock_openai.return_value = MagicMock()
        mock_async_openai.return_value = MagicMock()
        yield {"openai": mock_openai, "async_openai": mock_async_openai}


@pytest.fixture(scope="session")
def tests_root() -> Path:
    """
    Root directory for tests.
    Returns:
        Path to the tests directory.
    """
    return Path(__file__).parent.resolve()


@pytest.fixture(scope="session")
def data_dir(tests_root: Path) -> Path:
    """
    Directory containing test data files.
    Returns:
        Path to tests/data.
    """
    d = tests_root / "data"
    d.mkdir(parents=True, exist_ok=True)
    return d


@pytest.fixture(scope="session")
def input_data_dir(data_dir: Path) -> Path:
    """
    Directory containing input test data files.
    Returns:
        Path to tests/data/input.
    """
    d = data_dir / "input"
    d.mkdir(parents=True, exist_ok=True)
    return d


@pytest.fixture
def make_routine():
    """
    Factory fixture to create Routine with hardcoded defaults.
    
    Usage:
        routine = make_routine(operations=[...])
        routine = make_routine(operations=[...], parameters=[...], name="custom")
    """
    def factory(operations: list[RoutineOperationUnion], **kwargs: Any) -> Routine:
        defaults = {
            "name": "test_routine",
            "description": "Test routine",
        }
        return Routine(operations=operations, **{**defaults, **kwargs})
    
    return factory
