"""Schedule next-run computation and cron stepping."""

from datetime import datetime, timezone
from types import SimpleNamespace

from server.background.schedule_runner import (
    _compute_next_cron_run,
    compute_schedule_next_run,
)


def test_compute_next_cron_run_beijing_wall_0200():
    """cron 0 2 * * * = Beijing 02:00, not UTC 02:00."""
    after = datetime(2026, 6, 7, 17, 59, tzinfo=timezone.utc)  # Beijing 2026-06-08 01:59
    nxt = _compute_next_cron_run("0 2 * * *", after)
    assert nxt == datetime(2026, 6, 7, 18, 0, 0)


def test_compute_schedule_next_run_once_future():
    schedule = SimpleNamespace(
        enabled=True,
        run_mode="once",
        fire_at=datetime(2026, 12, 1, 10, 0),
        last_run_at=None,
        cron_expr=None,
    )
    now = datetime(2026, 6, 7, 12, 0, tzinfo=timezone.utc)
    assert compute_schedule_next_run(schedule, now) == schedule.fire_at


def test_compute_schedule_next_run_once_already_ran():
    schedule = SimpleNamespace(
        enabled=True,
        run_mode="once",
        fire_at=datetime(2026, 12, 1, 10, 0),
        last_run_at=datetime(2026, 12, 1, 10, 1),
        cron_expr=None,
    )
    now = datetime(2026, 6, 7, 12, 0, tzinfo=timezone.utc)
    assert compute_schedule_next_run(schedule, now) is None


def test_compute_schedule_next_run_cron_disabled():
    schedule = SimpleNamespace(
        enabled=False,
        run_mode="cron",
        cron_expr="*/5 * * * *",
        last_run_at=None,
        fire_at=None,
    )
    assert compute_schedule_next_run(schedule) is None
