"""Schedule cycle ↔ cron conversion (mirrors frontend scheduleCycle.ts / Baota crontab.py)."""

import pytest

from server.utils.schedule_cycle import (
    build_cron_from_cycle,
    format_cycle_label,
    parse_cron_to_cycle,
    SCHEDULE_MIN_INTERVAL_MINUTES,
)


@pytest.mark.parametrize(
    "cycle,expected",
    [
        ({"type": "day", "minute": 0, "hour": 2}, "0 2 * * *"),
        ({"type": "day-n", "minute": 30, "hour": 3, "interval": 2}, "30 3 */2 * *"),
        ({"type": "hour", "minute": 15}, "15 * * * *"),
        ({"type": "hour-n", "minute": 5, "interval": 4}, "5 */4 * * *"),
        ({"type": "minute-n", "interval": 10}, "*/10 * * * *"),
        ({"type": "week", "minute": 0, "hour": 9, "week": 1}, "0 9 * * 1"),
        ({"type": "month", "minute": 0, "hour": 1, "monthDay": 15}, "0 1 15 * *"),
    ],
)
def test_build_cron_from_cycle(cycle, expected):
    assert build_cron_from_cycle(cycle) == expected


def test_minute_n_minimum_interval():
    assert SCHEDULE_MIN_INTERVAL_MINUTES == 1
    assert build_cron_from_cycle({"type": "minute-n", "interval": 1}) == "*/1 * * * *"


@pytest.mark.parametrize(
    "cycle",
    [
        {"type": "day", "minute": 0, "hour": 2},
        {"type": "day-n", "minute": 30, "hour": 3, "interval": 2},
        {"type": "hour", "minute": 15},
        {"type": "hour-n", "minute": 5, "interval": 4},
        {"type": "minute-n", "interval": 10},
        {"type": "week", "minute": 0, "hour": 9, "week": 1},
        {"type": "month", "minute": 0, "hour": 1, "monthDay": 15},
    ],
)
def test_build_parse_roundtrip(cycle):
    cron = build_cron_from_cycle(cycle)
    parsed = parse_cron_to_cycle(cron)
    assert parsed["type"] == cycle["type"]
    assert build_cron_from_cycle(parsed) == cron


@pytest.mark.parametrize(
    "cron,expected_type",
    [
        ("0 2 * * *", "day"),
        ("30 3 */2 * *", "day-n"),
        ("15 * * * *", "hour"),
        ("5 */4 * * *", "hour-n"),
        ("*/10 * * * *", "minute-n"),
        ("0 9 * * 1", "week"),
        ("0 1 15 * *", "month"),
    ],
)
def test_parse_cron_roundtrip_type(cron, expected_type):
    parsed = parse_cron_to_cycle(cron)
    assert parsed["type"] == expected_type
    assert build_cron_from_cycle(parsed) == cron


def test_format_cycle_label_day():
    assert format_cycle_label("0 2 * * *") == "当天 02:00"


def test_unknown_cron_custom():
    parsed = parse_cron_to_cycle("0 0 1 1 *")
    assert parsed["type"] == "custom"
