import CoreFoundation
import CoreGraphics
import CoreMedia
import CoreVideo
import Darwin
import Foundation
import IOSurface
import ScreenCaptureKit
import VideoToolbox

@inline(__always)
private func liveDeskFlock(_ descriptor: Int32, _ operation: Int32) -> Int32 {
    flock(descriptor, operation)
}

private final class LiveDeskCaptureProcessLock {
    private static let defaultLockPath = "/tmp/livedesk-sck-h264-\(getuid()).lock"
    private var descriptors: [Int32]

    private init(descriptors: [Int32]) {
        self.descriptors = descriptors
    }

    static func resolvedPath() throws -> String {
        let configured = ProcessInfo.processInfo.environment["LIVEDESK_MAC_CAPTURE_LOCK_PATH"]?
            .trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
        if configured.isEmpty {
            return defaultLockPath
        }
        guard configured.hasPrefix("/"), configured.utf8.count <= 1024 else {
            throw LiveDeskSCKError.captureLockUnsafe(EINVAL)
        }
        return configured
    }

    static func acquire(
        ownerKind: String,
        inheritAcrossExec: Bool = false
    ) throws -> LiveDeskCaptureProcessLock {
        let lockPath = try resolvedPath()
        let rawMonitor = ProcessInfo.processInfo.environment["LIVEDESK_MAC_CAPTURE_MONITOR"]
        if let rawMonitor = rawMonitor {
            guard let monitor = Int(rawMonitor), monitor >= 0, monitor < 64 else {
                throw LiveDeskSCKError.captureLockUnsafe(EINVAL)
            }
            // Shared base lock excludes older whole-device helpers. The second
            // exclusive lock excludes every other owner of this monitor.
            let shared = try openLock(path: lockPath, operation: LOCK_SH, inheritAcrossExec: inheritAcrossExec)
            do {
                let selected = try openLock(path: "\(lockPath).monitor-\(monitor)", operation: LOCK_EX,
                                            inheritAcrossExec: inheritAcrossExec)
                fputs("LiveDeskCaptureLock state=acquired pid=\(getpid()) owner=\(ownerKind) monitor=\(monitor) inherited=\(inheritAcrossExec ? 1 : 0)\n", stderr)
                fflush(stderr)
                return LiveDeskCaptureProcessLock(descriptors: [selected, shared])
            } catch {
                _ = liveDeskFlock(shared, LOCK_UN)
                Darwin.close(shared)
                throw error
            }
        }
        let descriptor = try openLock(path: lockPath, operation: LOCK_EX, inheritAcrossExec: inheritAcrossExec)
        fputs(
            "LiveDeskCaptureLock state=acquired pid=\(getpid()) owner=\(ownerKind) path=\(lockPath) inherited=\(inheritAcrossExec ? 1 : 0)\n",
            stderr)
        fflush(stderr)
        return LiveDeskCaptureProcessLock(descriptors: [descriptor])
    }

    private static func openLock(path lockPath: String, operation: Int32, inheritAcrossExec: Bool) throws -> Int32 {
        let closeOnExecFlag = inheritAcrossExec ? 0 : O_CLOEXEC
        let descriptor = Darwin.open(
            lockPath,
            O_CREAT | O_RDWR | O_NOFOLLOW | closeOnExecFlag,
            S_IRUSR | S_IWUSR)
        guard descriptor >= 0 else {
            throw LiveDeskSCKError.captureLockOpen(errno)
        }

        var lockInfo = stat()
        guard Darwin.fstat(descriptor, &lockInfo) == 0 else {
            let lockError = errno
            Darwin.close(descriptor)
            throw LiveDeskSCKError.captureLockOpen(lockError)
        }
        guard lockInfo.st_uid == getuid(),
              (lockInfo.st_mode & mode_t(S_IFMT)) == mode_t(S_IFREG),
              lockInfo.st_nlink == 1 else {
            Darwin.close(descriptor)
            throw LiveDeskSCKError.captureLockUnsafe(EPERM)
        }

        guard liveDeskFlock(descriptor, operation | LOCK_NB) == 0 else {
            let lockError = errno
            Darwin.close(descriptor)
            throw LiveDeskSCKError.captureAlreadyActive(lockError)
        }

        if lockPath == defaultLockPath {
            _ = Darwin.fchmod(descriptor, S_IRUSR | S_IWUSR)
        }
        return descriptor
    }

    func release() {
        let current = descriptors
        descriptors = []
        for descriptor in current {
            _ = liveDeskFlock(descriptor, LOCK_UN)
            Darwin.close(descriptor)
        }
    }

    deinit {
        release()
    }
}

@available(macOS 12.3, *)
final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamDelegate {
    private struct EncodedAccessUnit {
        let bytes: Data
        let isKeyFrame: Bool
        let discontinuityBefore: Bool
        let timestampUs: Int64
        let durationUs: UInt32
        let queuedAtUptimeNs: UInt64
        let producedAtMonotonicNanoseconds: UInt64
    }

    private struct OutputEnqueueResult {
        let queued: Bool
        let droppedAccessUnits: Int
        let requestKeyFrame: Bool
    }

    private struct PendingEncodeFrame {
        let imageBuffer: CVPixelBuffer
        let presentationTime: CMTime
        let idle: Bool
        let capturedAtMonotonicNanoseconds: UInt64
    }

    private let maximumEncodeFramesInFlight = 2
    private let maximumPendingAccessUnits = 3
    private let maximumPendingOutputBytes = 8 * 1024 * 1024
    private let maximumAccessUnitBytes = 3 * 1024 * 1024
    private let maximumPendingOutputAgeNs: UInt64 = 120_000_000
    private let outputDrainTimeoutSeconds = 2.0
    private let idleKeepaliveIntervalNs: UInt64 = 500_000_000
    private let displayIndex: Int
    private let width: Int
    private let height: Int
    private let fps: Int
    private let bitrateKbps: Int
    private let queue = DispatchQueue(label: "dev.livedesk.screencapturekit.frames", qos: .userInteractive)
    private let outputWriterQueue = DispatchQueue(label: "dev.livedesk.screencapturekit.stdout", qos: .userInitiated)
    private let outputDrainGroup = DispatchGroup()
    private let outputLock = NSLock()
    private let metricsLock = NSLock()
    private let lifecycleLock = NSLock()
    private var stream: SCStream?
    private var compressionSession: VTCompressionSession?
    private var pendingOutputAccessUnits: [EncodedAccessUnit] = []
    private var pendingOutputBytes = 0
    private var outputQueueHighWatermark = 0
    private var outputDrainScheduled = false
    private var outputAccepting = true
    private var outputAwaitingKeyFrame = false
    private var outputFailureErrno: Int32?
    private var streamStopErrorDescription: String?
    private var streamStopErrorDomain: String?
    private var streamStopErrorCode: Int?
    private var shutdownStarted = false
    private var sampleCount: Int64 = 0
    private var frameCount: Int64 = 0
    private var skippedCount: Int64 = 0
    private var compressionOutputCount: Int64 = 0
    private var encodedCount: Int64 = 0
    private var encodedKeyCount: Int64 = 0
    private var encodedDeltaCount: Int64 = 0
    private var encodeFramesInFlight = 0
    private var nextEncodeOwnerToken: UInt64 = 0
    private var encodeOwnerCaptureTimestampByToken: [UInt64: UInt64] = [:]
    private var encodeOwnerHighWatermark = 0
    private var pendingEncodeFrame: PendingEncodeFrame?
    private var pendingEncodeDrainScheduled = false
    private var encodeInputAccepting = true
    private var encodeBackpressureCoalescedCount: Int64 = 0
    private var encodePendingReplacedCount: Int64 = 0
    private var encodeBackpressureSkippedCount: Int64 = 0
    private var idleKeepaliveSkippedCount: Int64 = 0
    private var outputQueueDroppedCount: Int64 = 0
    private var annexBAccessUnitAllocationCount: Int64 = 0
    private var annexBPayloadCopyCount: Int64 = 0
    private var annexBPayloadCopiedBytes: Int64 = 0
    private var forceNextKeyFrame = false
    private var hardwareAccelerationState: Int = -1
    private var hardwareAccelerationQueryStatus: OSStatus = noErr
    private var selectedDisplayID: CGDirectDisplayID = 0
    private var metricsWindowStartedAtNs = DispatchTime.now().uptimeNanoseconds
    private var metricsWindowSampleCount: Int64 = 0
    private var metricsWindowCompressionOutputCount: Int64 = 0
    private var metricsWindowEncodedCount: Int64 = 0
    private var metricsWindowBackpressureCoalescedCount: Int64 = 0
    private var metricsWindowBackpressureSkippedCount: Int64 = 0
    private var metricsWindowIdleSkippedCount: Int64 = 0
    private var lastEncodeSubmissionAtNs: UInt64 = 0
    private var lastCompleteImageBuffer: CVPixelBuffer?
    private var idleKeepaliveTimer: DispatchSourceTimer?
    private var lastEncodePresentationTime = CMTime.invalid
    private var loggedInputSurface = false
    private var compressionSessionActiveCount = 0
    private var compressionSessionHighWatermark = 0

    init(displayIndex: Int, width: Int, height: Int, fps: Int, bitrateKbps: Int) {
        precondition(
            MemoryLayout<(UInt64, UInt64, UInt64, UInt64)>.size == 32,
            "LiveDeskSCK framed stdout header must remain exactly 32 bytes")
        self.displayIndex = max(0, displayIndex)
        self.width = max(2, width)
        self.height = max(2, height)
        self.fps = max(1, fps)
        self.bitrateKbps = max(500, bitrateKbps)
        super.init()
        encodeOwnerCaptureTimestampByToken.reserveCapacity(
            maximumEncodeFramesInFlight)
    }

    func start() async throws {
        var runError: Error?
        do {
            fputs("LiveDeskSCK stage=shareable-content-request displayIndex=\(displayIndex)\n", stderr)
            let shareableContent = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)
            fputs("LiveDeskSCK stage=shareable-content-ready displays=\(shareableContent.displays.count)\n", stderr)
            try Task.checkCancellation()
            guard !shareableContent.displays.isEmpty else {
                throw LiveDeskSCKError.noDisplays
            }

            let mainDisplayID = CGMainDisplayID()
            let orderedDisplays = shareableContent.displays.sorted { left, right in
                let leftIsMain = left.displayID == mainDisplayID
                let rightIsMain = right.displayID == mainDisplayID
                if leftIsMain != rightIsMain {
                    return leftIsMain
                }
                return left.displayID < right.displayID
            }
            let display = orderedDisplays[min(displayIndex, orderedDisplays.count - 1)]
            selectedDisplayID = display.displayID
            fputs("LiveDeskSCK stage=encoder-create displayID=\(display.displayID)\n", stderr)
            try createCompressionSession()
            let filter = SCContentFilter(display: display, excludingWindows: [])
            let configuration = SCStreamConfiguration()
            configuration.width = width
            configuration.height = height
            configuration.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale(fps))
            configuration.queueDepth = 3
            configuration.showsCursor = true
            configuration.pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange

            let stream = SCStream(filter: filter, configuration: configuration, delegate: self)
            try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: queue)
            self.stream = stream
            fputs("LiveDeskSCK stage=capture-start-request displayID=\(display.displayID)\n", stderr)
            try await stream.startCapture()
            startIdleKeepaliveTimer()

            fputs("LiveDeskSCK stage=capture-started displayIndex=\(displayIndex) displayID=\(display.displayID) size=\(width)x\(height) fps=\(fps) bitrateKbps=\(bitrateKbps)\n", stderr)
            while !Task.isCancelled {
                try await Task.sleep(nanoseconds: 100_000_000)
                if let terminalError = terminalErrorIfPresent() {
                    throw terminalError
                }
                emitMetricsIfNeeded()
            }
        } catch is CancellationError {
            // Cancellation is an owned shutdown request, not a helper failure.
        } catch {
            runError = error
        }

        await stopCaptureAndDrainOutput()
        if let runError {
            throw runError
        }
    }

    private func createCompressionSession() throws {
        guard compressionSession == nil else {
            throw LiveDeskSCKError.encoderOwnership("compression session already exists")
        }
        var session: VTCompressionSession?
        let encoderSpecification: [CFString: Any] = [
            kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder: true,
            kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder: true
        ]
        let imageBufferAttributes: [CFString: Any] = [
            kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
            kCVPixelBufferWidthKey: NSNumber(value: width),
            kCVPixelBufferHeightKey: NSNumber(value: height),
            kCVPixelBufferMetalCompatibilityKey: true,
            kCVPixelBufferIOSurfacePropertiesKey: [:] as CFDictionary
        ]
        let status = VTCompressionSessionCreate(
            allocator: kCFAllocatorDefault,
            width: Int32(width),
            height: Int32(height),
            codecType: kCMVideoCodecType_H264,
            encoderSpecification: encoderSpecification as CFDictionary,
            imageBufferAttributes: imageBufferAttributes as CFDictionary,
            compressedDataAllocator: nil,
            outputCallback: Self.compressionCallback,
            refcon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
            compressionSessionOut: &session)

        guard status == noErr, let session else {
            throw LiveDeskSCKError.encoderCreate(status)
        }

        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality, value: kCFBooleanTrue)
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowTemporalCompression, value: kCFBooleanTrue)
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxFrameDelayCount, value: NSNumber(value: 0))
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Baseline_AutoLevel)
        let recoveryKeyInterval = max(1, fps / 2)
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value: recoveryKeyInterval))
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, value: NSNumber(value: 0.5))
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: NSNumber(value: fps))
        VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: NSNumber(value: bitrateKbps * 1000))
        let prepareStatus = VTCompressionSessionPrepareToEncodeFrames(session)
        guard prepareStatus == noErr else {
            VTCompressionSessionInvalidate(session)
            throw LiveDeskSCKError.encoderPrepare(prepareStatus)
        }

        var hardwareAccelerationValue: CFTypeRef?
        let hardwareAccelerationStatus = VTSessionCopyProperty(
            session,
            key: kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder,
            allocator: kCFAllocatorDefault,
            valueOut: &hardwareAccelerationValue)
        let accelerationState: Int
        if hardwareAccelerationStatus == noErr,
           let number = hardwareAccelerationValue as? NSNumber {
            accelerationState = number.boolValue ? 1 : 0
        } else {
            accelerationState = -1
        }
        metricsLock.lock()
        hardwareAccelerationState = accelerationState
        hardwareAccelerationQueryStatus = hardwareAccelerationStatus
        metricsLock.unlock()
        guard hardwareAccelerationStatus == noErr, accelerationState == 1 else {
            VTCompressionSessionInvalidate(session)
            throw LiveDeskSCKError.hardwareEncoderRequired(
                queryStatus: hardwareAccelerationStatus,
                reportedState: accelerationState)
        }

        compressionSession = session
        metricsLock.lock()
        let existingCompressionSessionCount = compressionSessionActiveCount
        if existingCompressionSessionCount == 0 {
            compressionSessionActiveCount = 1
            compressionSessionHighWatermark = max(
                compressionSessionHighWatermark,
                compressionSessionActiveCount)
        }
        metricsLock.unlock()
        guard existingCompressionSessionCount == 0 else {
            VTCompressionSessionInvalidate(session)
            compressionSession = nil
            throw LiveDeskSCKError.encoderOwnership(
                "compression session ledger was already \(existingCompressionSessionCount)")
        }
        emitMetricsIfNeeded(force: true)
    }

    private static let compressionCallback: VTCompressionOutputCallback = { refCon, sourceFrameRefCon, status, _, sampleBuffer in
        guard let refCon else {
            return
        }

        let encoder = Unmanaged<LiveDeskScreenCaptureKitEncoder>.fromOpaque(refCon).takeUnretainedValue()
        let encodeOwnerToken = sourceFrameRefCon.map {
            UInt64(UInt(bitPattern: $0))
        }
        encoder.handleCompressionOutput(
            encodeOwnerToken: encodeOwnerToken,
            status: status,
            sampleBuffer: sampleBuffer)
    }

    private func startIdleKeepaliveTimer() {
        precondition(idleKeepaliveTimer == nil)
        let interval = DispatchTimeInterval.nanoseconds(
            Int(idleKeepaliveIntervalNs))
        let timer = DispatchSource.makeTimerSource(queue: queue)
        timer.schedule(
            deadline: .now() + interval,
            repeating: interval,
            leeway: .milliseconds(50))
        timer.setEventHandler { [weak self] in
            self?.submitIdleKeepaliveIfDue()
        }
        idleKeepaliveTimer = timer
        timer.resume()
    }

    private func cancelIdleKeepaliveTimer() {
        let timer = idleKeepaliveTimer
        idleKeepaliveTimer = nil
        timer?.setEventHandler {}
        timer?.cancel()
    }

    private func submitIdleKeepaliveIfDue() {
        guard let imageBuffer = lastCompleteImageBuffer else {
            return
        }
        let nowNs = DispatchTime.now().uptimeNanoseconds
        let capturedAtMonotonicNanoseconds =
            clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)
        var reservation: (frame: PendingEncodeFrame, frameCount: Int64)?

        metricsLock.lock()
        let keepaliveDue = lastEncodeSubmissionAtNs != 0
            && nowNs >= lastEncodeSubmissionAtNs
            && nowNs - lastEncodeSubmissionAtNs >= idleKeepaliveIntervalNs
        if encodeInputAccepting,
           keepaliveDue,
           encodeFramesInFlight < maximumEncodeFramesInFlight,
           pendingEncodeFrame == nil {
            frameCount += 1
            encodeFramesInFlight += 1
            forceNextKeyFrame = false
            lastEncodeSubmissionAtNs = nowNs
            reservation = (
                frame: PendingEncodeFrame(
                    imageBuffer: imageBuffer,
                    presentationTime: .invalid,
                    idle: true,
                    capturedAtMonotonicNanoseconds:
                        capturedAtMonotonicNanoseconds),
                frameCount: frameCount)
        }
        metricsLock.unlock()

        guard let reservation else {
            emitMetricsIfNeeded()
            return
        }
        submitEncodeFrame(
            reservation.frame,
            frameCount: reservation.frameCount,
            forceRecoveryKeyFrame: true)
    }

    func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) {
        guard type == .screen else {
            return
        }

        let capturedAtMonotonicNanoseconds =
            clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)
        let disposition = frameDisposition(sampleBuffer)
        let sampleDataReady = CMSampleBufferDataIsReady(sampleBuffer)
        let currentImageBuffer = sampleDataReady
            ? CMSampleBufferGetImageBuffer(sampleBuffer)
            : nil
        if disposition.encodable,
           !disposition.idle,
           let currentImageBuffer {
            // ScreenCaptureKit idle samples can omit a new IOSurface. Retain
            // only the latest complete pixel buffer so a bounded idle
            // key-frame keepalive can reuse the current desktop image.
            lastCompleteImageBuffer = currentImageBuffer
        }
        let imageBuffer = currentImageBuffer
            ?? (disposition.idle ? lastCompleteImageBuffer : nil)
        let nowNs = DispatchTime.now().uptimeNanoseconds
        let idleKeepaliveDue = disposition.idle
            && (lastEncodeSubmissionAtNs == 0
                || nowNs < lastEncodeSubmissionAtNs
                || nowNs - lastEncodeSubmissionAtNs >= idleKeepaliveIntervalNs)
        let cadenceAllowsEncode = !disposition.idle || idleKeepaliveDue
        let samplePresentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        let candidateFrame = imageBuffer.map {
            PendingEncodeFrame(
                imageBuffer: $0,
                presentationTime: samplePresentationTime,
                idle: disposition.idle,
                capturedAtMonotonicNanoseconds:
                    capturedAtMonotonicNanoseconds)
        }
        var reservation: (frame: PendingEncodeFrame, frameCount: Int64, forceRecoveryKeyFrame: Bool)?

        metricsLock.lock()
        sampleCount += 1
        if !disposition.encodable || candidateFrame == nil {
            skippedCount += 1
        } else if !cadenceAllowsEncode {
            skippedCount += 1
            idleKeepaliveSkippedCount += 1
        } else if !encodeInputAccepting {
            skippedCount += 1
        } else if encodeFramesInFlight >= maximumEncodeFramesInFlight {
            encodeBackpressureCoalescedCount += 1
            if pendingEncodeFrame != nil {
                // The previous pending frame is the only frame actually
                // discarded. Replacing it keeps capture latency bounded to the
                // newest desktop while retaining exactly one pending owner.
                skippedCount += 1
                encodeBackpressureSkippedCount += 1
                encodePendingReplacedCount += 1
            }
            pendingEncodeFrame = candidateFrame
        } else {
            if pendingEncodeFrame != nil {
                // A VT completion can free a slot while its serial drain is
                // queued behind a newer ScreenCaptureKit callback. Never submit
                // that newer frame while retaining an older pending owner:
                // discard the stale pending frame and use the current pixels.
                skippedCount += 1
                encodeBackpressureSkippedCount += 1
                encodePendingReplacedCount += 1
                pendingEncodeFrame = nil
            }
            frameCount += 1
            encodeFramesInFlight += 1
            let forceRecoveryKeyFrame = forceNextKeyFrame
            forceNextKeyFrame = false
            lastEncodeSubmissionAtNs = nowNs
            reservation = (
                frame: candidateFrame!,
                frameCount: frameCount,
                forceRecoveryKeyFrame: forceRecoveryKeyFrame)
        }
        metricsLock.unlock()

        guard let reservation else {
            emitMetricsIfNeeded()
            return
        }
        submitEncodeFrame(
            reservation.frame,
            frameCount: reservation.frameCount,
            forceRecoveryKeyFrame: reservation.forceRecoveryKeyFrame)
    }

    private func submitEncodeFrame(
        _ frame: PendingEncodeFrame,
        frameCount currentFrameCount: Int64,
        forceRecoveryKeyFrame: Bool
    ) {
        guard let session = compressionSession else {
            finishEncodeFrame()
            fputs("LiveDeskSCK invariant failed: an accepted frame has no compression session.\n", stderr)
            fflush(stderr)
            Darwin._exit(18)
        }
        let imageBuffer = frame.imageBuffer
        if !loggedInputSurface {
            loggedInputSurface = true
            let pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer)
            let hasIOSurface = CVPixelBufferGetIOSurface(imageBuffer) != nil
            fputs("LiveDeskSCK input pixelFormat=\(pixelFormat) iosurface=\(hasIOSurface ? 1 : 0) queueDepth=3 zeroCopyCandidate=\(hasIOSurface ? 1 : 0)\n", stderr)
        }
        let duration = CMTime(value: 1, timescale: CMTimeScale(fps))
        let samplePresentationTime = frame.presentationTime
        let pts: CMTime
        if samplePresentationTime.isValid,
           (!lastEncodePresentationTime.isValid
            || CMTimeCompare(samplePresentationTime, lastEncodePresentationTime) > 0) {
            pts = samplePresentationTime
        } else if lastEncodePresentationTime.isValid {
            // Reused idle buffers do not always carry a fresh timestamp. Keep
            // VideoToolbox input strictly monotonic without retaining a queue
            // of old ScreenCaptureKit samples.
            pts = CMTimeAdd(lastEncodePresentationTime, duration)
        } else {
            pts = CMTime(value: currentFrameCount, timescale: CMTimeScale(fps))
        }
        lastEncodePresentationTime = pts
        var frameProperties: CFDictionary?
        if currentFrameCount == 1 || frame.idle || forceRecoveryKeyFrame {
            let properties = NSMutableDictionary()
            properties[kVTEncodeFrameOptionKey_ForceKeyFrame] = kCFBooleanTrue
            frameProperties = properties
        }

        let encodeOwnerToken = reserveEncodeOwner(
            capturedAtMonotonicNanoseconds:
                frame.capturedAtMonotonicNanoseconds)
        guard let sourceFrameRefcon =
            UnsafeMutableRawPointer(bitPattern: UInt(encodeOwnerToken)) else {
            releaseEncodeOwner(encodeOwnerToken)
            finishEncodeFrame()
            fputs("LiveDeskSCK invariant failed: encode owner token became nil.\n", stderr)
            fflush(stderr)
            Darwin._exit(20)
        }
        let status = VTCompressionSessionEncodeFrame(
            session,
            imageBuffer: imageBuffer,
            presentationTimeStamp: pts,
            duration: duration,
            frameProperties: frameProperties,
            sourceFrameRefcon: sourceFrameRefcon,
            infoFlagsOut: nil)

        if status != noErr {
            releaseEncodeOwner(encodeOwnerToken)
            finishEncodeFrame()
            if forceRecoveryKeyFrame {
                requestRecoveryKeyFrame()
            }
        }
        if status != noErr && (currentFrameCount == 1 || currentFrameCount % 120 == 0) {
            fputs("LiveDeskSCK encode status=\(status) frames=\(currentFrameCount)\n", stderr)
        }
        emitMetricsIfNeeded()
    }

    private func drainLatestPendingEncodeFrame() {
        var reservation: (frame: PendingEncodeFrame, frameCount: Int64, forceRecoveryKeyFrame: Bool)?
        metricsLock.lock()
        pendingEncodeDrainScheduled = false
        if encodeInputAccepting,
           encodeFramesInFlight < maximumEncodeFramesInFlight,
           let pendingFrame = pendingEncodeFrame {
            pendingEncodeFrame = nil
            frameCount += 1
            encodeFramesInFlight += 1
            let forceRecoveryKeyFrame = forceNextKeyFrame
            forceNextKeyFrame = false
            lastEncodeSubmissionAtNs = DispatchTime.now().uptimeNanoseconds
            reservation = (
                frame: pendingFrame,
                frameCount: frameCount,
                forceRecoveryKeyFrame: forceRecoveryKeyFrame)
        } else if !encodeInputAccepting {
            pendingEncodeFrame = nil
        }
        metricsLock.unlock()

        guard let reservation else {
            emitMetricsIfNeeded()
            return
        }
        submitEncodeFrame(
            reservation.frame,
            frameCount: reservation.frameCount,
            forceRecoveryKeyFrame: reservation.forceRecoveryKeyFrame)
    }

    func stream(_ stream: SCStream, didStopWithError error: Error) {
        fputs("LiveDeskSCK stream stopped: \(error)\n", stderr)
        lifecycleLock.lock()
        if !shutdownStarted && streamStopErrorDescription == nil {
            let nsError = error as NSError
            streamStopErrorDescription = String(describing: error)
            streamStopErrorDomain = nsError.domain
            streamStopErrorCode = nsError.code
        }
        lifecycleLock.unlock()
    }

    private func frameDisposition(_ sampleBuffer: CMSampleBuffer) -> (encodable: Bool, idle: Bool) {
        guard let attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, createIfNecessary: false) as NSArray?,
              let first = attachments.firstObject as? NSDictionary,
              let rawStatus = first[SCStreamFrameInfo.status] as? Int else {
            return (true, false)
        }
        if rawStatus == SCFrameStatus.complete.rawValue {
            return (true, false)
        }
        if rawStatus == SCFrameStatus.idle.rawValue {
            // A static desktop still needs a periodic current key frame for a
            // newly attached Wall/Control decoder. Encoding every idle callback
            // wastes capture and VideoToolbox budget, so retain a bounded 2 fps
            // key-frame keepalive instead.
            return (true, true)
        }
        return (false, false)
    }

    private func handleCompressionOutput(
        encodeOwnerToken: UInt64?,
        status: OSStatus,
        sampleBuffer: CMSampleBuffer?
    ) {
        let capturedAtMonotonicNanoseconds =
            takeEncodeOwnerCaptureTimestamp(encodeOwnerToken)
        defer {
            // The slot protects only VideoToolbox work plus the owned AU copy.
            // stdout is independently bounded and must never backpressure the
            // capture callback or retain its sample buffer.
            finishEncodeFrame()
        }
        guard status == noErr,
              let sampleBuffer,
              CMSampleBufferDataIsReady(sampleBuffer) else {
            return
        }
        recordCompressionOutput()
        guard let accessUnit = makeEncodedAccessUnit(
            sampleBuffer,
            capturedAtMonotonicNanoseconds:
                capturedAtMonotonicNanoseconds) else {
            return
        }
        let result = enqueueEncodedAccessUnit(accessUnit)
        recordEnqueueResult(result)
    }

    private func finishEncodeFrame() {
        var shouldSchedulePendingDrain = false
        var underflow = false
        metricsLock.lock()
        if encodeFramesInFlight <= 0 {
            underflow = true
        } else {
            encodeFramesInFlight -= 1
        }
        if encodeInputAccepting,
           pendingEncodeFrame != nil,
           !pendingEncodeDrainScheduled {
            pendingEncodeDrainScheduled = true
            shouldSchedulePendingDrain = true
        }
        metricsLock.unlock()

        if underflow {
            fputs("LiveDeskSCK invariant failed: encode in-flight ownership underflow.\n", stderr)
            fflush(stderr)
            Darwin._exit(17)
        }
        if shouldSchedulePendingDrain {
            queue.async {
                self.drainLatestPendingEncodeFrame()
            }
        }
    }

    private func reserveEncodeOwner(
        capturedAtMonotonicNanoseconds: UInt64
    ) -> UInt64 {
        var token: UInt64 = 0
        var overflow = false
        metricsLock.lock()
        if encodeOwnerCaptureTimestampByToken.count
            >= maximumEncodeFramesInFlight {
            overflow = true
        } else {
            repeat {
                nextEncodeOwnerToken &+= 1
            } while nextEncodeOwnerToken == 0
                || encodeOwnerCaptureTimestampByToken[
                    nextEncodeOwnerToken] != nil
            token = nextEncodeOwnerToken
            encodeOwnerCaptureTimestampByToken[token] =
                capturedAtMonotonicNanoseconds
            encodeOwnerHighWatermark = max(
                encodeOwnerHighWatermark,
                encodeOwnerCaptureTimestampByToken.count)
        }
        metricsLock.unlock()
        if overflow {
            fputs("LiveDeskSCK invariant failed: encode timestamp owner exceeded two in-flight frames.\n", stderr)
            fflush(stderr)
            Darwin._exit(20)
        }
        return token
    }

    private func releaseEncodeOwner(_ token: UInt64) {
        metricsLock.lock()
        let removed = encodeOwnerCaptureTimestampByToken.removeValue(
            forKey: token)
        metricsLock.unlock()
        if removed == nil {
            fputs("LiveDeskSCK invariant failed: encode timestamp owner was already released.\n", stderr)
            fflush(stderr)
            Darwin._exit(20)
        }
    }

    private func takeEncodeOwnerCaptureTimestamp(
        _ token: UInt64?
    ) -> UInt64 {
        guard let token, token != 0 else {
            fputs("LiveDeskSCK invariant failed: VideoToolbox callback omitted its encode timestamp owner.\n", stderr)
            fflush(stderr)
            Darwin._exit(20)
        }
        metricsLock.lock()
        let capturedAt = encodeOwnerCaptureTimestampByToken.removeValue(
            forKey: token)
        metricsLock.unlock()
        guard let capturedAt, capturedAt > 0 else {
            fputs("LiveDeskSCK invariant failed: VideoToolbox callback returned an unknown encode timestamp owner.\n", stderr)
            fflush(stderr)
            Darwin._exit(20)
        }
        return capturedAt
    }

    private func recordCompressionOutput() {
        metricsLock.lock()
        compressionOutputCount += 1
        metricsLock.unlock()
    }

    private func recordEnqueueResult(_ result: OutputEnqueueResult) {
        metricsLock.lock()
        outputQueueDroppedCount += Int64(max(0, result.droppedAccessUnits))
        if result.requestKeyFrame {
            forceNextKeyFrame = true
        }
        metricsLock.unlock()
    }

    func requestRecoveryKeyFrame() {
        metricsLock.lock()
        forceNextKeyFrame = true
        metricsLock.unlock()
    }

    private func emitMetricsIfNeeded(force: Bool = false) {
        let nowNs = DispatchTime.now().uptimeNanoseconds
        let outputSnapshot = snapshotOutputQueue()
        var metricsLine: String?

        metricsLock.lock()
        let elapsedNs = nowNs >= metricsWindowStartedAtNs
            ? nowNs - metricsWindowStartedAtNs
            : 0
        if force || elapsedNs >= 1_000_000_000 {
            let elapsedSeconds = max(0.001, Double(elapsedNs) / 1_000_000_000.0)
            let captureFps = Double(sampleCount - metricsWindowSampleCount) / elapsedSeconds
            let compressionFps = Double(compressionOutputCount - metricsWindowCompressionOutputCount) / elapsedSeconds
            let encodedFps = Double(encodedCount - metricsWindowEncodedCount) / elapsedSeconds
            let captureFpsText = String(format: "%.2f", locale: Locale(identifier: "en_US_POSIX"), captureFps)
            let compressionFpsText = String(format: "%.2f", locale: Locale(identifier: "en_US_POSIX"), compressionFps)
            let encodedFpsText = String(format: "%.2f", locale: Locale(identifier: "en_US_POSIX"), encodedFps)
            let backpressureCoalescedInWindow = max(
                0,
                encodeBackpressureCoalescedCount - metricsWindowBackpressureCoalescedCount)
            let backpressureSkippedInWindow = max(
                0,
                encodeBackpressureSkippedCount - metricsWindowBackpressureSkippedCount)
            let idleSkippedInWindow = max(
                0,
                idleKeepaliveSkippedCount - metricsWindowIdleSkippedCount)
            metricsLine = "LiveDeskSCK metrics v=5 hw=\(hardwareAccelerationState) hwStatus=\(hardwareAccelerationQueryStatus) displayID=\(selectedDisplayID) captureFps=\(captureFpsText) compressionFps=\(compressionFpsText) encodedFps=\(encodedFpsText) captureSamples=\(sampleCount) encodable=\(frameCount) skipped=\(skippedCount) compressionOutputs=\(compressionOutputCount) encoded=\(encodedCount) inFlight=\(encodeFramesInFlight) pendingEncode=\(pendingEncodeFrame == nil ? 0 : 1) encodeOwnerDepth=\(encodeOwnerCaptureTimestampByToken.count) encodeOwnerHighWatermark=\(encodeOwnerHighWatermark) backpressureCoalesced=\(backpressureCoalescedInWindow) backpressureSkipped=\(backpressureSkippedInWindow) pendingReplaced=\(encodePendingReplacedCount) idleSkipped=\(idleSkippedInWindow) vtActive=\(compressionSessionActiveCount) vtHighWatermark=\(compressionSessionHighWatermark) outputDepth=\(outputSnapshot.depth) outputBytes=\(outputSnapshot.bytes) outputOldestAgeMs=\(outputSnapshot.oldestAgeMs) outputHighWatermark=\(outputSnapshot.highWatermark) outputDropped=\(outputQueueDroppedCount) outputAwaitingKey=\(outputSnapshot.awaitingKeyFrame ? 1 : 0) annexBAllocations=\(annexBAccessUnitAllocationCount) annexBPayloadCopies=\(annexBPayloadCopyCount) annexBPayloadCopiedBytes=\(annexBPayloadCopiedBytes)"
            metricsWindowStartedAtNs = nowNs
            metricsWindowSampleCount = sampleCount
            metricsWindowCompressionOutputCount = compressionOutputCount
            metricsWindowEncodedCount = encodedCount
            metricsWindowBackpressureCoalescedCount = encodeBackpressureCoalescedCount
            metricsWindowBackpressureSkippedCount = encodeBackpressureSkippedCount
            metricsWindowIdleSkippedCount = idleKeepaliveSkippedCount
        }
        metricsLock.unlock()

        if let metricsLine {
            fputs("\(metricsLine)\n", stderr)
        }
    }

    private func makeEncodedAccessUnit(
        _ sampleBuffer: CMSampleBuffer,
        capturedAtMonotonicNanoseconds: UInt64
    ) -> EncodedAccessUnit? {
        guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else {
            return nil
        }

        let keyFrame = isKeyFrame(sampleBuffer)
        var output = Data()
        var payloadCopyCount: Int64 = 0
        var payloadCopiedBytes: Int64 = 0
        appendAccessUnitDelimiter(to: &output)
        if keyFrame, let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer) {
            for parameterSetIndex in 0...1 {
                let copiedBytes = appendParameterSet(
                    formatDescription,
                    index: parameterSetIndex,
                    to: &output)
                if copiedBytes > 0 {
                    payloadCopyCount += 1
                    payloadCopiedBytes += Int64(copiedBytes)
                }
            }
        }

        var lengthAtOffset = 0
        var totalLength = 0
        var dataPointer: UnsafeMutablePointer<Int8>?
        let status = CMBlockBufferGetDataPointer(
            blockBuffer,
            atOffset: 0,
            lengthAtOffsetOut: &lengthAtOffset,
            totalLengthOut: &totalLength,
            dataPointerOut: &dataPointer)

        guard status == noErr, let dataPointer, totalLength > 4 else {
            return nil
        }

        var offset = 0
        while offset + 4 <= totalLength {
            var nalLength: UInt32 = 0
            memcpy(&nalLength, dataPointer.advanced(by: offset), 4)
            nalLength = CFSwapInt32BigToHost(nalLength)
            let length = Int(nalLength)
            if length <= 0 || offset + 4 + length > totalLength {
                break
            }

            appendStartCode(to: &output)
            output.append(UnsafeRawPointer(dataPointer.advanced(by: offset + 4)).assumingMemoryBound(to: UInt8.self), count: length)
            payloadCopyCount += 1
            payloadCopiedBytes += Int64(length)
            offset += 4 + length
        }

        guard !output.isEmpty else {
            return nil
        }
        let fallbackDurationUs = UInt32(max(1, 1_000_000 / max(1, fps)))
        let timestampUs = mediaTimeMicroseconds(
            CMSampleBufferGetPresentationTimeStamp(sampleBuffer),
            fallback: max(0, frameCount) * Int64(fallbackDurationUs))
        let durationValue = mediaTimeMicroseconds(
            CMSampleBufferGetDuration(sampleBuffer),
            fallback: Int64(fallbackDurationUs))
        let durationUs = UInt32(
            max(1, min(Int64(UInt32.max), durationValue)))
        metricsLock.lock()
        annexBAccessUnitAllocationCount += 1
        annexBPayloadCopyCount += payloadCopyCount
        annexBPayloadCopiedBytes += payloadCopiedBytes
        metricsLock.unlock()
        return EncodedAccessUnit(
            bytes: output,
            isKeyFrame: keyFrame,
            discontinuityBefore: false,
            timestampUs: timestampUs,
            durationUs: durationUs,
            queuedAtUptimeNs: DispatchTime.now().uptimeNanoseconds,
            producedAtMonotonicNanoseconds:
                capturedAtMonotonicNanoseconds)
    }

    private func mediaTimeMicroseconds(_ value: CMTime, fallback: Int64) -> Int64 {
        guard value.isValid else {
            return max(0, fallback)
        }
        let seconds = CMTimeGetSeconds(value)
        guard seconds.isFinite, seconds >= 0 else {
            return max(0, fallback)
        }
        let microseconds = seconds * 1_000_000.0
        guard microseconds <= Double(Int64.max) else {
            return max(0, fallback)
        }
        return max(0, Int64(microseconds.rounded(.towardZero)))
    }

    private func markingDiscontinuity(
        _ accessUnit: EncodedAccessUnit
    ) -> EncodedAccessUnit {
        guard !accessUnit.discontinuityBefore else {
            return accessUnit
        }
        return EncodedAccessUnit(
            bytes: accessUnit.bytes,
            isKeyFrame: accessUnit.isKeyFrame,
            discontinuityBefore: true,
            timestampUs: accessUnit.timestampUs,
            durationUs: accessUnit.durationUs,
            queuedAtUptimeNs: accessUnit.queuedAtUptimeNs,
            producedAtMonotonicNanoseconds:
                accessUnit.producedAtMonotonicNanoseconds)
    }

    private func enqueueEncodedAccessUnit(_ accessUnit: EncodedAccessUnit) -> OutputEnqueueResult {
        var queued = false
        var droppedAccessUnits = 0
        var requestKeyFrame = false
        var shouldScheduleDrain = false
        let nowNs = DispatchTime.now().uptimeNanoseconds

        outputLock.lock()
        if !outputAccepting {
            droppedAccessUnits = 1
        } else if accessUnit.bytes.count > maximumAccessUnitBytes {
            droppedAccessUnits = pendingOutputAccessUnits.count + 1
            pendingOutputAccessUnits.removeAll(keepingCapacity: true)
            pendingOutputBytes = 0
            outputAwaitingKeyFrame = true
            requestKeyFrame = true
        } else if outputAwaitingKeyFrame {
            if accessUnit.isKeyFrame {
                droppedAccessUnits = pendingOutputAccessUnits.count
                pendingOutputAccessUnits.removeAll(keepingCapacity: true)
                pendingOutputBytes = 0
                outputAwaitingKeyFrame = false
                pendingOutputAccessUnits.append(
                    markingDiscontinuity(accessUnit))
                pendingOutputBytes = accessUnit.bytes.count
                queued = true
            } else {
                droppedAccessUnits = 1
                requestKeyFrame = true
            }
        } else {
            let oldestAgeExceeded: Bool
            if let oldest = pendingOutputAccessUnits.first,
               nowNs >= oldest.queuedAtUptimeNs {
                oldestAgeExceeded =
                    nowNs - oldest.queuedAtUptimeNs > maximumPendingOutputAgeNs
            } else {
                oldestAgeExceeded = false
            }
            let wouldOverflow = oldestAgeExceeded
                || pendingOutputAccessUnits.count >= maximumPendingAccessUnits
                || pendingOutputBytes + accessUnit.bytes.count > maximumPendingOutputBytes
            if wouldOverflow {
                droppedAccessUnits = pendingOutputAccessUnits.count
                pendingOutputAccessUnits.removeAll(keepingCapacity: true)
                pendingOutputBytes = 0
                if accessUnit.isKeyFrame {
                    pendingOutputAccessUnits.append(
                        markingDiscontinuity(accessUnit))
                    pendingOutputBytes = accessUnit.bytes.count
                    queued = true
                } else {
                    droppedAccessUnits += 1
                    outputAwaitingKeyFrame = true
                    requestKeyFrame = true
                }
            } else {
                pendingOutputAccessUnits.append(accessUnit)
                pendingOutputBytes += accessUnit.bytes.count
                queued = true
            }
        }

        if queued {
            outputQueueHighWatermark = max(outputQueueHighWatermark, pendingOutputAccessUnits.count)
            if !outputDrainScheduled {
                outputDrainScheduled = true
                outputDrainGroup.enter()
                shouldScheduleDrain = true
            }
        }
        outputLock.unlock()

        if shouldScheduleDrain {
            outputWriterQueue.async {
                self.drainPendingOutput()
            }
        }

        return OutputEnqueueResult(
            queued: queued,
            droppedAccessUnits: droppedAccessUnits,
            requestKeyFrame: requestKeyFrame)
    }

    private func drainPendingOutput() {
        defer {
            outputDrainGroup.leave()
        }

        while true {
            let accessUnit: EncodedAccessUnit
            outputLock.lock()
            if pendingOutputAccessUnits.isEmpty {
                outputDrainScheduled = false
                outputLock.unlock()
                return
            }
            accessUnit = pendingOutputAccessUnits.removeFirst()
            pendingOutputBytes = max(0, pendingOutputBytes - accessUnit.bytes.count)
            outputLock.unlock()

            if let writeError = writeFramedAccessUnitToStdout(accessUnit) {
                outputLock.lock()
                let droppedAccessUnits = pendingOutputAccessUnits.count + 1
                pendingOutputAccessUnits.removeAll(keepingCapacity: true)
                pendingOutputBytes = 0
                outputAccepting = false
                outputAwaitingKeyFrame = true
                outputFailureErrno = writeError
                outputDrainScheduled = false
                outputLock.unlock()

                recordEnqueueResult(OutputEnqueueResult(
                    queued: false,
                    droppedAccessUnits: droppedAccessUnits,
                    requestKeyFrame: false))
                fputs("LiveDeskSCK stdout write failed errno=\(writeError).\n", stderr)
                return
            }

            recordWrittenAccessUnit(accessUnit)
        }
    }

    private func writeFramedAccessUnitToStdout(
        _ accessUnit: EncodedAccessUnit
    ) -> Int32? {
        var flags: UInt32 = accessUnit.isKeyFrame ? 1 : 0
        if accessUnit.discontinuityBefore {
            flags |= 1 << 1
        }
        var headerStorage = (UInt64(0), UInt64(0), UInt64(0), UInt64(0))
        let headerError = withUnsafeMutableBytes(of: &headerStorage) {
            rawBuffer -> Int32? in
            rawBuffer.storeBytes(
                of: UInt32(0x3148444c).littleEndian,
                toByteOffset: 0,
                as: UInt32.self)
            rawBuffer.storeBytes(
                of: UInt32(accessUnit.bytes.count).littleEndian,
                toByteOffset: 4,
                as: UInt32.self)
            rawBuffer.storeBytes(
                of: accessUnit.timestampUs.littleEndian,
                toByteOffset: 8,
                as: Int64.self)
            rawBuffer.storeBytes(
                of: flags.littleEndian,
                toByteOffset: 16,
                as: UInt32.self)
            rawBuffer.storeBytes(
                of: accessUnit.durationUs.littleEndian,
                toByteOffset: 20,
                as: UInt32.self)
            rawBuffer.storeBytes(
                of: accessUnit.producedAtMonotonicNanoseconds.littleEndian,
                toByteOffset: 24,
                as: UInt64.self)
            return writeAllToStdout(
                UnsafeRawBufferPointer(rawBuffer))
        }
        if let headerError {
            return headerError
        }
        return writeAllToStdout(accessUnit.bytes)
    }

    private func writeAllToStdout(_ data: Data) -> Int32? {
        data.withUnsafeBytes { (rawBuffer: UnsafeRawBufferPointer) -> Int32? in
            writeAllToStdout(rawBuffer)
        }
    }

    private func writeAllToStdout(
        _ rawBuffer: UnsafeRawBufferPointer
    ) -> Int32? {
        guard !rawBuffer.isEmpty, let baseAddress = rawBuffer.baseAddress else {
            return nil
        }

        var offset = 0
        while offset < rawBuffer.count {
            let written = Darwin.write(
                STDOUT_FILENO,
                baseAddress.advanced(by: offset),
                rawBuffer.count - offset)
            if written > 0 {
                offset += written
                continue
            }
            if written < 0 && errno == EINTR {
                continue
            }
            return written == 0 ? EPIPE : errno
        }
        return nil
    }

    private func recordWrittenAccessUnit(_ accessUnit: EncodedAccessUnit) {
        metricsLock.lock()
        encodedCount += 1
        if accessUnit.isKeyFrame {
            encodedKeyCount += 1
        } else {
            encodedDeltaCount += 1
        }
        let currentEncodedCount = encodedCount
        let currentEncodedKeyCount = encodedKeyCount
        let currentEncodedDeltaCount = encodedDeltaCount
        metricsLock.unlock()

        if currentEncodedCount == 1 {
            fputs("LiveDeskSCK encoded frames=\(currentEncodedCount) key=\(currentEncodedKeyCount) delta=\(currentEncodedDeltaCount) bytes=\(accessUnit.bytes.count)\n", stderr)
        }
        emitMetricsIfNeeded()
    }

    private func snapshotOutputQueue() -> (
        depth: Int,
        bytes: Int,
        oldestAgeMs: Int,
        highWatermark: Int,
        awaitingKeyFrame: Bool
    ) {
        outputLock.lock()
        let nowNs = DispatchTime.now().uptimeNanoseconds
        let oldestAgeMs: Int
        if let oldest = pendingOutputAccessUnits.first,
           nowNs >= oldest.queuedAtUptimeNs {
            oldestAgeMs = Int((nowNs - oldest.queuedAtUptimeNs) / 1_000_000)
        } else {
            oldestAgeMs = 0
        }
        let snapshot = (
            depth: pendingOutputAccessUnits.count,
            bytes: pendingOutputBytes,
            oldestAgeMs: oldestAgeMs,
            highWatermark: outputQueueHighWatermark,
            awaitingKeyFrame: outputAwaitingKeyFrame)
        outputLock.unlock()
        return snapshot
    }

    private func terminalErrorIfPresent() -> Error? {
        lifecycleLock.lock()
        let streamError = streamStopErrorDescription
        let streamErrorDomain = streamStopErrorDomain
        let streamErrorCode = streamStopErrorCode
        lifecycleLock.unlock()
        if let streamError {
            return LiveDeskSCKError.streamStopped(
                streamError,
                domain: streamErrorDomain ?? "",
                code: streamErrorCode ?? 0)
        }

        outputLock.lock()
        let writeError = outputFailureErrno
        outputLock.unlock()
        if let writeError {
            return LiveDeskSCKError.stdoutWrite(writeError)
        }
        return nil
    }

    private func stopCaptureAndDrainOutput() async {
        guard beginShutdown() else {
            return
        }
        cancelIdleKeepaliveTimer()

        let activeStream = stream
        stream = nil
        if let activeStream {
            do {
                try await activeStream.stopCapture()
            } catch {
                fputs("LiveDeskSCK stop capture failed: \(error)\n", stderr)
                fflush(stderr)
                // Capture is not proven stopped, so releasing an encoder whose
                // callback owns passUnretained(self) would be unsafe.
                Darwin._exit(14)
            }
        }

        drainCompressionSessionAfterCaptureStops()
        closeOutputQueue()
        fputs(
            "LiveDeskSCK stage=output-drain-start timeoutMs=\(Int(outputDrainTimeoutSeconds * 1000.0))\n",
            stderr)
        fflush(stderr)
        if !waitForOutputDrain() {
            let snapshot = snapshotOutputQueue()
            fputs("LiveDeskSCK stdout drain timed out depth=\(snapshot.depth) bytes=\(snapshot.bytes).\n", stderr)
            fflush(stderr)
            Darwin._exit(13)
        }
        fputs("LiveDeskSCK stage=output-drain-complete\n", stderr)
        fflush(stderr)
        // Terminal zero is trusted only after the ordered output-drain
        // completion ACK above. Earlier idle metrics are operational samples,
        // never shutdown proof.
        emitMetricsIfNeeded(force: true)
    }

    private func beginShutdown() -> Bool {
        lifecycleLock.lock()
        guard !shutdownStarted else {
            lifecycleLock.unlock()
            return false
        }
        shutdownStarted = true
        lifecycleLock.unlock()
        return true
    }

    private func drainCompressionSessionAfterCaptureStops() {
        // stopCapture prevents new samples. The serial barrier then proves no
        // capture callback can still submit into VideoToolbox before it drains.
        metricsLock.lock()
        encodeInputAccepting = false
        pendingEncodeFrame = nil
        metricsLock.unlock()
        queue.sync {}
        if let session = compressionSession {
            let completeStatus = VTCompressionSessionCompleteFrames(
                session,
                untilPresentationTimeStamp: .invalid)
            if completeStatus != noErr {
                fputs("LiveDeskSCK encoder drain status=\(completeStatus).\n", stderr)
                fflush(stderr)
                // A failed completion cannot prove that every unretained
                // VideoToolbox callback has returned.
                Darwin._exit(15)
            }
            metricsLock.lock()
            let remainingEncodeFrames = encodeFramesInFlight
            let remainingPendingFrameCount = pendingEncodeFrame == nil ? 0 : 1
            let pendingDrainStillScheduled = pendingEncodeDrainScheduled
            let activeCompressionSessions = compressionSessionActiveCount
            let remainingEncodeOwners =
                encodeOwnerCaptureTimestampByToken.count
            metricsLock.unlock()
            if remainingEncodeFrames != 0
                || remainingPendingFrameCount != 0
                || pendingDrainStillScheduled
                || remainingEncodeOwners != 0
                || activeCompressionSessions != 1 {
                fputs("LiveDeskSCK encoder drain invariant failed inFlight=\(remainingEncodeFrames) pending=\(remainingPendingFrameCount) pendingDrain=\(pendingDrainStillScheduled ? 1 : 0) encodeOwners=\(remainingEncodeOwners) vtActive=\(activeCompressionSessions).\n", stderr)
                fflush(stderr)
                Darwin._exit(16)
            }
            VTCompressionSessionInvalidate(session)
            compressionSession = nil
            metricsLock.lock()
            compressionSessionActiveCount -= 1
            let terminalCompressionSessionCount = compressionSessionActiveCount
            metricsLock.unlock()
            if terminalCompressionSessionCount != 0 {
                fputs("LiveDeskSCK encoder terminal invariant failed vtActive=\(terminalCompressionSessionCount).\n", stderr)
                fflush(stderr)
                Darwin._exit(19)
            }
        }
        lastCompleteImageBuffer = nil
        lastEncodePresentationTime = .invalid
    }

    private func closeOutputQueue() {
        outputLock.lock()
        outputAccepting = false
        outputLock.unlock()
    }

    private func waitForOutputDrain() -> Bool {
        let drainDeadline = DispatchTime.now()
            + .milliseconds(Int(outputDrainTimeoutSeconds * 1000.0))
        return outputDrainGroup.wait(timeout: drainDeadline) == .success
    }

    private func isKeyFrame(_ sampleBuffer: CMSampleBuffer) -> Bool {
        guard let attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, createIfNecessary: false) as NSArray?,
              let first = attachments.firstObject as? NSDictionary else {
            return true
        }
        return !(first[kCMSampleAttachmentKey_NotSync] as? Bool ?? false)
    }

    private func appendParameterSet(_ formatDescription: CMFormatDescription, index: Int, to output: inout Data) -> Int {
        var pointer: UnsafePointer<UInt8>?
        var size = 0
        var count = 0
        var nalHeaderLength: Int32 = 0
        let status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
            formatDescription,
            parameterSetIndex: index,
            parameterSetPointerOut: &pointer,
            parameterSetSizeOut: &size,
            parameterSetCountOut: &count,
            nalUnitHeaderLengthOut: &nalHeaderLength)

        guard status == noErr, let pointer, size > 0 else {
            return 0
        }

        appendStartCode(to: &output)
        output.append(pointer, count: size)
        return size
    }

    private func appendStartCode(to output: inout Data) {
        output.append(contentsOf: [0, 0, 0, 1])
    }

    private func appendAccessUnitDelimiter(to output: inout Data) {
        appendStartCode(to: &output)
        output.append(contentsOf: [0x09, 0xF0])
    }
}

enum LiveDeskSCKError: Error {
    case noDisplays
    case encoderCreate(OSStatus)
    case encoderPrepare(OSStatus)
    case hardwareEncoderRequired(queryStatus: OSStatus, reportedState: Int)
    case encoderOwnership(String)
    case captureLockOpen(Int32)
    case captureLockUnsafe(Int32)
    case captureAlreadyActive(Int32)
    case lockedExecutableExec(Int32)
    case streamStopped(String, domain: String, code: Int)
    case stdoutWrite(Int32)
}

func screenRecordingPermissionDeniedDetails(_ error: Error) -> (domain: String, code: Int)? {
    if case let LiveDeskSCKError.streamStopped(_, domain, code) = error {
        return domain == SCStreamErrorDomain
                && code == SCStreamError.Code.userDeclined.rawValue
            ? (domain, code)
            : nil
    }

    let nsError = error as NSError
    return nsError.domain == SCStreamErrorDomain
            && nsError.code == SCStreamError.Code.userDeclined.rawValue
        ? (nsError.domain, nsError.code)
        : nil
}

func intArg(_ name: String, default defaultValue: Int) -> Int {
    let args = CommandLine.arguments
    guard let index = args.firstIndex(of: name), index + 1 < args.count else {
        return defaultValue
    }
    return Int(args[index + 1]) ?? defaultValue
}

@main
struct LiveDeskSCKMain {
    private static func runLockedCompatibilityExecutable() -> Never {
        let executableArguments = Array(CommandLine.arguments.dropFirst(2))
        guard let executablePath = executableArguments.first,
              executablePath.hasPrefix("/"),
              !executablePath.isEmpty else {
            fputs("LiveDeskCaptureLock failed: locked executable path is missing or not absolute.\n", stderr)
            exit(18)
        }

        do {
            let captureLock = try LiveDeskCaptureProcessLock.acquire(
                ownerKind: "ffmpeg-avfoundation-videotoolbox",
                inheritAcrossExec: true)
            defer {
                captureLock.release()
            }

            var cArguments: [UnsafeMutablePointer<CChar>?] =
                executableArguments.map { argument in
                    argument.withCString { strdup($0) }
                }
            guard cArguments.allSatisfy({ $0 != nil }) else {
                for case let pointer? in cArguments {
                    free(pointer)
                }
                throw LiveDeskSCKError.lockedExecutableExec(ENOMEM)
            }
            cArguments.append(nil)
            defer {
                for case let pointer? in cArguments {
                    free(pointer)
                }
            }

            let execResult = executablePath.withCString { executablePointer in
                cArguments.withUnsafeMutableBufferPointer { argumentBuffer in
                    Darwin.execv(executablePointer, argumentBuffer.baseAddress!)
                }
            }
            let execError = errno
            if execResult != 0 {
                throw LiveDeskSCKError.lockedExecutableExec(execError)
            }
            exit(127)
        } catch LiveDeskSCKError.captureAlreadyActive(let lockError) {
            fputs(
                "LiveDeskCaptureLock failed: capture lock is already owned by another VuvoDesk helper errno=\(lockError).\n",
                stderr)
            exit(12)
        } catch LiveDeskSCKError.captureLockOpen(let lockError) {
            fputs("LiveDeskCaptureLock failed: capture lock could not be opened errno=\(lockError).\n", stderr)
            exit(18)
        } catch LiveDeskSCKError.captureLockUnsafe(let lockError) {
            fputs("LiveDeskCaptureLock failed: capture lock path is unsafe errno=\(lockError).\n", stderr)
            exit(18)
        } catch {
            fputs("LiveDeskCaptureLock failed: \(error)\n", stderr)
            exit(127)
        }
    }

    static func main() async {
        _ = Darwin.signal(SIGPIPE, SIG_IGN)
        if CommandLine.arguments.count >= 2,
           CommandLine.arguments[1] == "--livedesk-exec-locked" {
            runLockedCompatibilityExecutable()
        }
        _ = Darwin.signal(SIGTERM, SIG_IGN)
        _ = Darwin.signal(SIGINT, SIG_IGN)
        _ = Darwin.signal(SIGUSR1, SIG_IGN)
        guard #available(macOS 12.3, *) else {
            fputs("LiveDeskSCK requires macOS 12.3 or later.\n", stderr)
            exit(2)
        }
        fputs("LiveDeskSCK stage=process-start macOS=\(ProcessInfo.processInfo.operatingSystemVersionString)\n", stderr)

        let displayIndex = intArg("--display-index", default: 0)
        let width = intArg("--width", default: 960)
        let height = intArg("--height", default: 540)
        let fps = intArg("--fps", default: 30)
        let bitrateKbps = intArg("--bitrate-kbps", default: max(3500, width * height * fps / 4000))

        do {
            let captureLock = try LiveDeskCaptureProcessLock.acquire(
                ownerKind: "screencapturekit-videotoolbox")
            defer {
                captureLock.release()
            }
            let encoder = LiveDeskScreenCaptureKitEncoder(displayIndex: displayIndex, width: width, height: height, fps: fps, bitrateKbps: bitrateKbps)
            let encoderTask = Task {
                try await encoder.start()
            }
            let signalQueue = DispatchQueue(
                label: "com.livedesk.screencapturekit.termination",
                qos: .userInitiated)
            let terminationSignals = [SIGTERM, SIGINT].map { signalNumber in
                let source = DispatchSource.makeSignalSource(
                    signal: signalNumber,
                    queue: signalQueue)
                source.setEventHandler {
                    fputs("LiveDeskSCK stage=cooperative-stop-request signal=\(signalNumber)\n", stderr)
                    fflush(stderr)
                    encoderTask.cancel()
                }
                source.resume()
                return source
            }
            let recoverySignal = DispatchSource.makeSignalSource(
                signal: SIGUSR1,
                queue: signalQueue)
            recoverySignal.setEventHandler {
                encoder.requestRecoveryKeyFrame()
            }
            recoverySignal.resume()
            defer {
                for source in terminationSignals {
                    source.cancel()
                }
                recoverySignal.cancel()
            }
            try await encoderTask.value
        } catch LiveDeskSCKError.captureAlreadyActive(let lockError) {
            fputs("LiveDeskSCK failed: capture lock is already owned by another VuvoDesk helper errno=\(lockError).\n", stderr)
            exit(12)
        } catch LiveDeskSCKError.captureLockOpen(let lockError) {
            fputs("LiveDeskSCK failed: capture lock could not be opened errno=\(lockError).\n", stderr)
            exit(18)
        } catch LiveDeskSCKError.captureLockUnsafe(let lockError) {
            fputs("LiveDeskSCK failed: capture lock path is unsafe errno=\(lockError).\n", stderr)
            exit(18)
        } catch {
            if let permissionError = screenRecordingPermissionDeniedDetails(error) {
                fputs("LiveDeskSCK screen recording permission is not granted domain=\(permissionError.domain) code=\(permissionError.code).\n", stderr)
                exit(10)
            }
            fputs("LiveDeskSCK failed: \(error)\n", stderr)
            exit(1)
        }
    }
}
