"""
Tests for GateWay Scheduler Service Module.
"""


import pytest
import pytest_asyncio

from verlex_server.gateway.backend.scheduler_service import (
    SchedulerConfig,
    SchedulerMetrics,
    SchedulerService,
    SchedulerStatus,
)


class TestSchedulerConfig:
    """Tests for SchedulerConfig dataclass."""

    def test_default_config(self):
        """Test default configuration values."""
        config = SchedulerConfig()

        assert config.poll_interval_seconds == 0.1
        assert config.max_concurrent_jobs == 10
        assert config.max_retries == 3

    def test_custom_config(self):
        """Test custom configuration values."""
        config = SchedulerConfig(
            poll_interval_seconds=0.5,
            max_concurrent_jobs=50,
            max_retries=5,
        )

        assert config.poll_interval_seconds == 0.5
        assert config.max_concurrent_jobs == 50
        assert config.max_retries == 5

    def test_config_to_dict(self):
        """Test config serialization."""
        config = SchedulerConfig(
            max_concurrent_jobs=20,
        )

        data = config.to_dict()

        assert "poll_interval_seconds" in data
        assert "max_concurrent_jobs" in data


class TestSchedulerMetrics:
    """Tests for SchedulerMetrics dataclass."""

    def test_default_metrics(self):
        """Test default metrics values."""
        metrics = SchedulerMetrics()

        assert metrics.jobs_scheduled == 0
        assert metrics.jobs_completed == 0
        assert metrics.jobs_failed == 0

    def test_metrics_to_dict(self):
        """Test metrics serialization."""
        metrics = SchedulerMetrics()
        metrics.jobs_scheduled = 10
        metrics.jobs_completed = 8

        data = metrics.to_dict()

        assert data["jobs_scheduled"] == 10
        assert data["jobs_completed"] == 8
        assert "success_rate" in data


class TestSchedulerService:
    """Tests for SchedulerService."""

    @pytest.fixture
    def config(self):
        return SchedulerConfig(
            poll_interval_seconds=0.1,
            max_concurrent_jobs=10,
        )

    @pytest_asyncio.fixture
    async def scheduler(self, config):
        return SchedulerService(config=config)

    @pytest.mark.asyncio
    async def test_initial_status(self, scheduler):
        """Test initial scheduler status."""
        assert scheduler.status == SchedulerStatus.STOPPED

    @pytest.mark.asyncio
    async def test_start_stop(self, scheduler):
        """Test starting and stopping scheduler."""
        await scheduler.start()

        assert scheduler.status == SchedulerStatus.RUNNING

        await scheduler.stop()

        assert scheduler.status == SchedulerStatus.STOPPED

    @pytest.mark.asyncio
    async def test_double_start(self, scheduler):
        """Test starting scheduler twice is safe."""
        await scheduler.start()
        await scheduler.start()  # Should not raise

        assert scheduler.status == SchedulerStatus.RUNNING

        await scheduler.stop()

    @pytest.mark.asyncio
    async def test_stop_when_not_running(self, scheduler):
        """Test stopping scheduler when not running is safe."""
        await scheduler.stop()  # Should not raise

        assert scheduler.status == SchedulerStatus.STOPPED

    @pytest.mark.asyncio
    async def test_get_metrics(self, scheduler):
        """Test getting scheduler metrics."""
        metrics = scheduler.get_metrics()

        assert isinstance(metrics, dict)
        assert "jobs_scheduled" in metrics

    @pytest.mark.asyncio
    async def test_get_status_info(self, scheduler):
        """Test getting scheduler status info."""
        info = scheduler.get_status_info()

        assert "status" in info
        assert "metrics" in info
        assert info["status"] == "stopped"


class TestSchedulerServiceWithQueue:
    """Tests for scheduler with actual queue operations."""

    @pytest_asyncio.fixture
    async def scheduler(self):
        config = SchedulerConfig(
            poll_interval_seconds=0.05,
            max_concurrent_jobs=5,
        )
        return SchedulerService(config=config)

    @pytest.mark.asyncio
    async def test_graceful_shutdown(self, scheduler):
        """Test graceful shutdown."""
        await scheduler.start()

        # Graceful stop should wait for jobs
        await scheduler.stop(drain=True)

        assert scheduler.status == SchedulerStatus.STOPPED
