import sys
from pathlib import Path
from unittest.mock import MagicMock

import pytest

# Add the project root to Python path so imports work correctly
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))


@pytest.fixture
def mock_model_organism():
    """Fixture providing a mock ModelOrganism for testing."""
    from inspect_ai import TaskInfo

    from bench_af._abstract.objects import ModelOrganism

    mock_task = MagicMock(spec=TaskInfo)
    mock_task.name = "test_task"

    return ModelOrganism(
        name="test_model",
        model=MagicMock(),
        solver=MagicMock(),
        supported_environments={"test_task"},
        inspect_load_name="test/model",
    )


@pytest.fixture
def mock_detector():
    """Fixture providing a mock Detector for testing."""
    from inspect_ai import TaskInfo

    from bench_af._abstract.objects import Detector

    class TestDetector(Detector):
        def get_prediction(self, *, model_organism, task, eval_logs):
            return 0.6, "Test prediction"

    mock_task = MagicMock(spec=TaskInfo)
    mock_task.name = "test_task"

    return TestDetector(
        name="test_detector",
        supported_model_organisms={"test_model"},
        supported_environments={"test_task"},
    )


@pytest.fixture
def mock_task_info():
    """Fixture providing a mock TaskInfo for testing."""
    from inspect_ai import TaskInfo

    return TaskInfo(file="/path/to/test_task.py", name="test_task", attribs={})


@pytest.fixture
def mock_eval_log_success():
    """Fixture providing a successful mock EvalLog."""
    from inspect_ai.log import EvalLog

    mock_log = MagicMock(spec=EvalLog)
    mock_log.status = "success"
    mock_log.results = MagicMock()
    mock_log.results.metrics = {"accuracy": MagicMock(value=0.85)}
    return mock_log


@pytest.fixture
def mock_eval_log_error():
    """Fixture providing an error mock EvalLog."""
    from inspect_ai.log import EvalLog

    mock_log = MagicMock(spec=EvalLog)
    mock_log.status = "error"
    mock_log.error = "Test error message"
    return mock_log


@pytest.fixture(scope="session")
def ensure_default_files():
    """Ensure default model and task files exist for testing."""
    models_dir = Path("models")
    tasks_dir = Path("tasks")

    # Check if default files exist
    default_model = models_dir / "default.py"
    default_task = tasks_dir / "default.py"

    if not default_model.exists():
        pytest.skip("Default model file not found - some e2e tests will be skipped")

    if not default_task.exists():
        pytest.skip("Default task file not found - some e2e tests will be skipped")

    return True


# Test markers for organizing tests
def pytest_configure(config):
    """Configure custom pytest markers."""
    config.addinivalue_line("markers", "unit: mark test as a unit test")
    config.addinivalue_line("markers", "integration: mark test as an integration test")
    config.addinivalue_line("markers", "e2e: mark test as an end-to-end test")
    config.addinivalue_line("markers", "slow: mark test as slow running")


@pytest.fixture(autouse=True)
def setup_test_environment():
    """Setup test environment before each test."""
    # This could be used to set environment variables,
    # clear caches, or other test setup
    pass


# Mock fixtures for external dependencies
@pytest.fixture
def mock_openai_model():
    """Mock OpenAI model for testing without API calls."""
    mock_model = MagicMock()
    mock_model.name = "openai/gpt-4o"
    return mock_model


@pytest.fixture
def mock_inspect_eval():
    """Mock inspect_ai eval function to avoid actual model calls."""
    from inspect_ai.log import EvalLog

    def mock_eval(*args, **kwargs):
        mock_log = MagicMock(spec=EvalLog)
        mock_log.status = "success"
        mock_log.results = MagicMock()
        mock_log.results.metrics = {"accuracy": MagicMock(value=0.9)}
        return [mock_log]

    return mock_eval
