"""Tests for Sondeo structured logging and timeline collection."""

from sondeo import log, report
from sondeo.profiler.logging import clear_events, correlation_scope, get_events
from sondeo.profiler.memory import clear_results as clear_memory_results
from sondeo.profiler.timer import clear_results as clear_timer_results
from sondeo.profiler.timer import profile
from sondeo.profiler.trace import clear_results as clear_trace_results


def _clear_all() -> None:
    clear_events()
    clear_timer_results()
    clear_memory_results()
    clear_trace_results()


def test_log_decorator_captures_entry_and_exit() -> None:
    _clear_all()

    @log
    def add(a: int, b: int) -> int:
        return a + b

    assert add(2, 3) == 5

    events = get_events()
    assert len(events) == 2
    assert events[0].data["phase"] == "enter"
    assert events[1].data["phase"] == "exit"
    assert "args" in events[0].data
    assert events[1].data["return"] == "5"
    assert events[0].correlation_id == events[1].correlation_id

    _clear_all()


def test_log_message_inherits_correlation_id() -> None:
    _clear_all()

    with correlation_scope("abc123"):
        log("inside scope")

    events = get_events()
    assert len(events) == 1
    assert events[0].correlation_id == "abc123"

    _clear_all()


def test_profile_and_log_share_correlation_id() -> None:
    _clear_all()

    @profile
    def run_job() -> None:
        log("running")

    run_job()

    events = get_events()
    profile_events = [event for event in events if event.event_type == "profile"]
    assert len(profile_events) == 2

    profile_cid = profile_events[0].correlation_id
    assert profile_cid is not None
    assert all(event.correlation_id == profile_cid for event in profile_events)

    log_event = next(
        event
        for event in events
        if event.event_type == "log" and event.message == "running"
    )
    assert log_event.correlation_id == profile_cid

    _clear_all()


def test_report_json_filters_timeline() -> None:
    _clear_all()

    log("db connected", module="app.db", level="info")
    log("cache miss", module="app.cache", level="debug")
    log("db failed", module="app.db", level="error")

    data = report(
        format="json",
        clear=False,
        include_modules=["app.db"],
        levels=["error"],
        pattern="failed",
    )

    timeline = data["timeline"]
    assert len(timeline) == 1
    assert timeline[0]["module"] == "app.db"
    assert timeline[0]["level"] == "error"
    assert "failed" in timeline[0]["message"]

    _clear_all()
