import os
import xml.etree.ElementTree as ET
from ..src.core.synchronizer import Synchronizer
from ..src.hardware.constraints import HardwareConstraints
from ..src.interfaces.xml_generator import XMLGenerator

def test_xml_generator_output_structure(tmp_path):
    hw = HardwareConstraints()
    # Определяем простую последовательность: RF блок без ADC, затем Grad блок с ADC
    blocks = [
        {"type": "RF", "duration": 1e-4, "has_adc": False},
        {"type": "GRAD", "duration": 2e-4, "has_adc": True}
    ]
    seq_data = {"blocks": blocks}
    # Генерируем события синхронизации
    events = Synchronizer(hw).process(seq_data)
    # Генерация XML в временный файл
    xml_path = tmp_path / "test_sync.xml"
    xml_gen = XMLGenerator()
    xml_gen.generate(events, str(xml_path), hw)
    # Чтение и парсинг XML
    tree = ET.parse(xml_path)
    root = tree.getroot()
    # Проверяем наличие основных разделов
    sections = [elem.tag for elem in root]
    assert "ParamCount" in sections and "RF" in sections and "SW" in sections and "ADC" in sections and "GR" in sections and "CL" in sections
    # Проверяем правильность ParamCount
    count = int(root.findtext("ParamCount"))
    assert count == len(events)
    # Проверяем значения триггеров RF, SW, ADC
    rf_values = [int(child.text) for child in root.find("RF")]
    sw_values = [int(child.text) for child in root.find("SW")]
    adc_values = [int(child.text) for child in root.find("ADC")]
    # Должно быть столько же значений, сколько событий
    assert len(rf_values) == count
    assert len(sw_values) == count
    assert len(adc_values) == count
    # Первый RF должен быть 0 (нет RF в начальной задержке), первый SW должен быть 1, первый ADC должен быть 0
    assert rf_values[0] == 0
    assert sw_values[0] == 1
    assert adc_values[0] == 0
    # Проверяем, что для RF-блока (второе событие RF) RF-триггер 1, ADC 0; для Grad-блока с ADC RF=0, ADC=1
    # События: [DELAY(start), DELAY(RF_delay), RF, GRAD, DELAY(TR_delay)]
    # RF-триггер должен быть 1 только на событии RF (индекс 2 списка events)
    assert rf_values[2] == 1 and all(val in (0, 1) for val in rf_values)
    # ADC-триггер должен быть 1 только на событии с ADC (Grad, индекс 3)
    assert adc_values[3] == 1 and all(val in (0, 1) for val in adc_values)
    # Проверяем секцию CL: количество тиков каждого события
    cl_values = [int(child.text) for child in root.find("CL")]
    # Количество CL значений равно числу событий, и первое значение соответствует стартовой задержке (в тиках)
    assert len(cl_values) == count
    start_delay_ticks = int(round(hw.START_DELAY / hw.MIN_BLOCK_DURATION))
    assert cl_values[0] == start_delay_ticks
