import os
from ..src.core.synchronizer import Synchronizer, TimingEvent
from ..src.hardware.constraints import HardwareConstraints

def test_synchronizer_adds_delays():
    hw = HardwareConstraints()  # используем значения по умолчанию
    # Два блока: RF (без ADC) и градиент (с ADC)
    blocks = [
        {"type": "RF", "duration": 1e-3, "has_adc": False},
        {"type": "GRAD", "duration": 2e-3, "has_adc": True}
    ]
    seq_data = {"blocks": blocks}
    synch = Synchronizer(hw)
    events = synch.process(seq_data)

    # Проверяем общее количество событий:
    # Ожидается: Start delay, RF delay, RF block, Grad block, TR delay = 5 событий
    assert isinstance(events, list) and all(isinstance(e, TimingEvent) for e in events)
    assert len(events) == 5

    # Проверяем последовательность типов событий
    types = [e.event_type for e in events]
    expected_types = ["DELAY", "DELAY", "RF", "GRAD", "DELAY"]
    assert types == expected_types

    # Проверяем, что первая задержка имеет длительность соответствующую START_DELAY
    start_delay_ticks = int(round(hw.START_DELAY / hw.MIN_BLOCK_DURATION))
    assert events[0].event_type == "DELAY"
    assert events[0].duration == start_delay_ticks

    # Проверяем, что RF_DELAY вставлена перед RF блоком
    rf_delay_ticks = int(round(hw.RF_DELAY / hw.MIN_BLOCK_DURATION))
    assert events[1].event_type == "DELAY" and events[2].event_type == "RF"
    assert events[1].duration == rf_delay_ticks

    # Проверяем, что TR_DELAY вставлена после градиентного блока с ADC
    tr_delay_ticks = int(round(hw.TR_DELAY / hw.MIN_BLOCK_DURATION))
    assert events[-1].event_type == "DELAY"
    assert events[-1].duration == tr_delay_ticks

def test_synchronizer_timing_order():
    hw = HardwareConstraints()
    blocks = [
        {"type": "GRAD", "duration": 5e-4, "has_adc": True},  # один блок с ADC
    ]
    events = Synchronizer(hw).process({"blocks": blocks})
    # Должно быть: начальная задержка, блок, TR задержка (3 события)
    assert events[0].start == 0  # начало первой задержки в 0
    # Проверяем, что время старта каждого следующего события больше или равно предыдущего конца
    for i in range(1, len(events)):
        prev = events[i-1]
        curr = events[i]
        # start текущего должен равняться start предыдущего + duration предыдущего
        assert curr.start == prev.start + prev.duration
