from __future__ import annotations

from pymulator.ui.connection_logs import ConnectionLogStore
from pymulator.sidecar.daemon import SidecarRuntime, _parse_semantic_log_line


def test_connection_log_store_tracks_active_and_history() -> None:
    store = ConnectionLogStore(history_limit=4, event_limit=16)

    session_id = store.begin("DoIP", "127.0.0.1:49152")
    store.append(
        session_id=session_id,
        direction="inbound",
        participants=["127.0.0.1:49152", "DoIP"],
        event="RX 16 byte(s)",
    )

    active = store.active_payload()
    assert active["active"] is True
    assert active["session"] is not None
    assert active["session"]["service"] == "DoIP"
    assert active["session"]["peer"] == "127.0.0.1:49152"

    store.end(session_id=session_id, reason="Connection closed")

    after = store.active_payload()
    assert after["active"] is False
    assert after["session"] is None
    assert after["historyCount"] == 1


def test_connection_log_store_strips_ansi_and_uses_latest_active() -> None:
    store = ConnectionLogStore(history_limit=2, event_limit=16)

    store.begin("HSFZ", "127.0.0.1:6801")
    store.append_to_latest(
        direction="inbound",
        participants=["Tester", "Engine ECU"],
        event="\x1b[1;33mEngine ECU\x1b[0m \x1b[1;33m<-\x1b[0m Service 0x10",
    )

    payload = store.active_payload()
    assert payload["active"] is True
    session = payload["session"]
    assert session is not None
    assert "Engine ECU <- Service 0x10" in [item["event"] for item in session["events"]]


def test_parse_semantic_log_line_extracts_direction_participants_and_event() -> None:
    direction, participants, event = _parse_semantic_log_line(
        "ecu ← Tester Present - with response",
        ecu_name="ecu",
        fallback_direction="request",
    )
    assert direction == "inbound"
    assert participants == ["Tester", "ecu"]
    assert event == "Tester Present - with response"

    direction, participants, event = _parse_semantic_log_line(
        "ecu → Positive Response to service 0x3E [00]",
        ecu_name="ecu",
        fallback_direction="response",
    )
    assert direction == "outbound"
    assert participants == ["ecu", "Tester"]
    assert event == "Positive Response to service 0x3E [00]"


def test_diagnostic_log_keeps_semantic_line_in_details() -> None:
    runtime = SidecarRuntime()
    runtime._connection_logs.begin("ECUconnect", "127.0.0.1:50000")
    runtime._on_diagnostic_log(
        {
            "ecu": "ecu",
            "direction": "request",
            "text": "ecu \u2190 Tester Present - with response",
            "timestamp": 100.0,
        }
    )

    payload = runtime.connection_log_active()
    assert payload["active"] is True
    session = payload["session"]
    assert session is not None
    last_event = session["events"][-1]
    assert last_event["event"] == "Tester Present - with response"
    assert last_event["details"]["semanticLine"] == "ecu \u2190 Tester Present - with response"


def test_clear_recent_frames_clears_bus_buffer_and_returns_status() -> None:
    class _DummyBus:
        def __init__(self) -> None:
            self._frames = ["Rx 0x7E0 [2] 10 03", "Tx 0x7E8 [3] 50 03 00"]

        def recent_frames(self) -> list[str]:
            return list(self._frames)

        def clear_recent_frames(self) -> None:
            self._frames.clear()

    runtime = SidecarRuntime()
    runtime._running = True
    runtime._spec_path = "specs/vehicle.json"
    runtime._options = {}
    runtime._bus = _DummyBus()
    runtime._services = []

    result = runtime.clear_recent_frames()

    assert result["running"] is True
    assert result["snapshot"]["recent_frames"] == []
