"""Unit tests for the cron pipeline schedule config."""

from __future__ import annotations

import pytest
from sqlalchemy.ext.asyncio import AsyncSession

from app.exceptions import ValidationError
from app.scheduler import SCHEDULE_DEFAULTS, validate_cron
from app.services.admin_service import get_schedule_config, update_schedule_config


@pytest.fixture
async def session() -> AsyncSession:
    from tests.conftest import _test_session_factory

    async with _test_session_factory() as session:
        yield session


class TestValidateCron:
    def test_accepts_valid(self):
        validate_cron("0 7 * * *", "Europe/Berlin")
        validate_cron("0 14-22 * * 1-5", "UTC")

    def test_rejects_bad_cron(self):
        with pytest.raises(Exception):
            validate_cron("not a cron", "UTC")

    def test_rejects_bad_timezone(self):
        with pytest.raises(Exception):
            validate_cron("0 7 * * *", "Mars/Phobos")


class TestScheduleConfig:
    async def test_defaults_when_unset(self, session: AsyncSession):
        config = await get_schedule_config(session)
        assert config == SCHEDULE_DEFAULTS

    async def test_update_and_read_back(self, session: AsyncSession):
        updated = await update_schedule_config(
            session, {"schedule_daily_pipeline_cron": "30 6 * * *"}
        )
        assert updated["schedule_daily_pipeline_cron"] == "30 6 * * *"
        # untouched keys keep their defaults
        assert updated["schedule_intraday_pipeline_cron"] == SCHEDULE_DEFAULTS["schedule_intraday_pipeline_cron"]

        config = await get_schedule_config(session)
        assert config["schedule_daily_pipeline_cron"] == "30 6 * * *"

    async def test_rejects_bad_cron(self, session: AsyncSession):
        with pytest.raises(ValidationError):
            await update_schedule_config(session, {"schedule_fundamentals_cron": "every monday"})

    async def test_rejects_bad_timezone(self, session: AsyncSession):
        with pytest.raises(ValidationError):
            await update_schedule_config(session, {"schedule_timezone": "Nowhere/Void"})

    async def test_rejects_unknown_key(self, session: AsyncSession):
        with pytest.raises(ValidationError):
            await update_schedule_config(session, {"schedule_bogus": "0 0 * * *"})
