import AVFoundation
import CoreVideo
import Foundation
import ScreenCaptureCore

/// Wraps an `AVCaptureSession` configured to deliver BGRA frames from an iOS
/// device to a `FrameWriter`.
final class DeviceCaptureSession: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
    private let session = AVCaptureSession()
    private let output = AVCaptureVideoDataOutput()
    private let writer: FrameWriter
    private let queue = DispatchQueue(label: "automobile.screen-capture.frames")

    init(writer: FrameWriter) {
        self.writer = writer
    }

    func start(device: AVCaptureDevice) throws {
        let input = try AVCaptureDeviceInput(device: device)

        session.beginConfiguration()
        if session.canAddInput(input) {
            session.addInput(input)
        }
        output.alwaysDiscardsLateVideoFrames = true
        output.videoSettings = [
            kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
        ]
        output.setSampleBufferDelegate(self, queue: queue)
        if session.canAddOutput(output) {
            session.addOutput(output)
        }
        session.commitConfiguration()
        session.startRunning()
    }

    func stop() {
        session.stopRunning()
    }

    func captureOutput(
        _ output: AVCaptureOutput,
        didOutput sampleBuffer: CMSampleBuffer,
        from connection: AVCaptureConnection
    ) {
        writer.write(sampleBuffer: sampleBuffer)
    }
}
