import pytest
from datetime import time, date, datetime, timedelta
from src.core.scheduler import ThrottledSchedulerConfigurator

# [DEF:test_throttled_scheduler:Module]
# @TIER: STANDARD
# @PURPOSE: Unit tests for ThrottledSchedulerConfigurator distribution logic.

def test_calculate_schedule_even_distribution():
    """
    @TEST_SCENARIO: 3 tasks in a 2-hour window should be spaced 1 hour apart.
    """
    start = time(1, 0)
    end = time(3, 0)
    dashboards = ["d1", "d2", "d3"]
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert len(schedule) == 3
    assert schedule[0] == datetime(2024, 1, 1, 1, 0)
    assert schedule[1] == datetime(2024, 1, 1, 2, 0)
    assert schedule[2] == datetime(2024, 1, 1, 3, 0)

def test_calculate_schedule_midnight_crossing():
    """
    @TEST_SCENARIO: Window from 23:00 to 01:00 (next day).
    """
    start = time(23, 0)
    end = time(1, 0)
    dashboards = ["d1", "d2", "d3"]
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert len(schedule) == 3
    assert schedule[0] == datetime(2024, 1, 1, 23, 0)
    assert schedule[1] == datetime(2024, 1, 2, 0, 0)
    assert schedule[2] == datetime(2024, 1, 2, 1, 0)

def test_calculate_schedule_single_task():
    """
    @TEST_SCENARIO: Single task should be scheduled at start time.
    """
    start = time(1, 0)
    end = time(2, 0)
    dashboards = ["d1"]
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert len(schedule) == 1
    assert schedule[0] == datetime(2024, 1, 1, 1, 0)

def test_calculate_schedule_empty_list():
    """
    @TEST_SCENARIO: Empty dashboard list returns empty schedule.
    """
    start = time(1, 0)
    end = time(2, 0)
    dashboards = []
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert schedule == []

def test_calculate_schedule_zero_window():
    """
    @TEST_SCENARIO: Window start == end. All tasks at start time.
    """
    start = time(1, 0)
    end = time(1, 0)
    dashboards = ["d1", "d2"]
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert len(schedule) == 2
    assert schedule[0] == datetime(2024, 1, 1, 1, 0)
    assert schedule[1] == datetime(2024, 1, 1, 1, 0)

def test_calculate_schedule_very_small_window():
    """
    @TEST_SCENARIO: Window smaller than number of tasks (in seconds).
    """
    start = time(1, 0, 0)
    end = time(1, 0, 1) # 1 second window
    dashboards = ["d1", "d2", "d3"]
    today = date(2024, 1, 1)
    
    schedule = ThrottledSchedulerConfigurator.calculate_schedule(start, end, dashboards, today)
    
    assert len(schedule) == 3
    assert schedule[0] == datetime(2024, 1, 1, 1, 0, 0)
    assert schedule[1] == datetime(2024, 1, 1, 1, 0, 0, 500000) # 0.5s
    assert schedule[2] == datetime(2024, 1, 1, 1, 0, 1)

# [/DEF:test_throttled_scheduler:Module]