import Foundation

private final class RunLoopTimeline: @unchecked Sendable {
    var tick = 0
    var previous = ContinuousClock.now
}

func runRunLoopLab() {
    labHeader(
        "RUN LOOP · Timer servicing and main-thread starvation",
        mechanism: "A run loop must regain control before it can dispatch timers or input."
    )

    let timeline = RunLoopTimeline()
    let timer = Timer(timeInterval: 0.10, repeats: true) { _ in
        let now = ContinuousClock.now
        let gap = timeline.previous.duration(to: now)
        let gapMS = Double(gap.components.seconds) * 1_000
            + Double(gap.components.attoseconds) / 1_000_000_000_000_000
        timeline.previous = now
        timeline.tick += 1

        print("tick \(timeline.tick) · gap \(formatMilliseconds(gapMS))")
        if timeline.tick == 3 {
            print("  ↳ deliberately blocking this thread for 350 ms")
            Thread.sleep(forTimeInterval: 0.35)
        }
    }

    RunLoop.current.add(timer, forMode: .default)
    RunLoop.current.run(until: Date(timeIntervalSinceNow: 1.05))
    timer.invalidate()

    print("Observation: the timer did not execute on another thread; its next dispatch waited for the run loop.")
    print("Interview link: the AppKit main run loop has the same servicing constraint for events, layout, and drawing.")
}
