//! Integration tests for the scheduled tasks (cron) system.
//! Run with: `cargo test --test test_scheduler`.

/// Verify that Schedule types (de)serialize correctly.
#[tokio::test]
async fn test_scheduler_types_roundtrip() {
    use picobot::scheduler::Schedule;

    let s1 = Schedule::Every { every_ms: 3600000 };
    let json = serde_json::to_string(&s1).unwrap();
    let s2: Schedule = serde_json::from_str(&json).unwrap();
    match s2 {
        Schedule::Every { every_ms } => assert_eq!(every_ms, 3600000),
        _ => panic!("expected Every"),
    }

    let s1 = Schedule::At { at: 1000000 };
    let json = serde_json::to_string(&s1).unwrap();
    let s2: Schedule = serde_json::from_str(&json).unwrap();
    match s2 {
        Schedule::At { at } => assert_eq!(at, 1000000),
        _ => panic!("expected At"),
    }

    let s1 = Schedule::Cron {
        expr: "0 0 9 * * *".into(),
        tz: None,
    };
    let json = serde_json::to_string(&s1).unwrap();
    let s2: Schedule = serde_json::from_str(&json).unwrap();
    match s2 {
        Schedule::Cron { expr, tz } => {
            assert_eq!(expr, "0 0 9 * * *");
            assert!(tz.is_none());
        }
        _ => panic!("expected Cron"),
    }
}

/// Verify that next_run_for_schedule produces valid future timestamps.
#[test]
fn test_next_run_always_future() {
    use picobot::scheduler::{Schedule, next_run_for_schedule};

    let now = 1700000000000_i64;

    let schedules = vec![
        Schedule::Every { every_ms: 60000 },
        Schedule::Cron {
            expr: "0 0 9 * * *".into(),
            tz: None,
        },
    ];

    for s in &schedules {
        let next = next_run_for_schedule(s, now);
        assert!(next.is_some(), "expected next run for {:?}", s);
        assert!(
            next.unwrap() > now,
            "next run should be after now for {:?}",
            s
        );
    }
}
