import AVFoundation

/// DecoderPort — Hexagonal port interface for platform decoder adapters.
///
/// The engine calls command methods (handleLoad, handlePlay, etc.) and
/// receives feedback via the DecoderEventCallbacks. The adapter
/// implementation is the ONLY code that touches platform playback APIs
/// (AVPlayer, ExoPlayer, etc.); everything crossing this interface speaks
/// the domain's vocabulary — URIs, milliseconds — never AVFoundation types.
/// (The one exception is DecoderLoadRequest's opaque interceptor cargo,
/// which only the default decoder reads.)
///
/// The default implementation is AVPlayerDecoderAdapter. Future adapters
/// (e.g., web audio, test doubles) conform to the same protocol. Code that
/// genuinely needs AVPlayer objects (video surfaces, ads) takes them from
/// the concrete adapter class, not from this protocol.
///
/// Threading: all methods must be called on the main thread. The bridge
/// dispatches to main before invoking.
protocol DecoderPort: AnyObject {
    /// Callbacks for reporting decoder events back to the engine.
    var callbacks: DecoderEventCallbacks { get set }

    /// Maximum forward buffer duration in seconds. 0 = system default.
    var maxBufferDuration: TimeInterval { get set }

    // MARK: - Playback Commands

    /// Load media per `request`. A prepared asset attached by an interceptor
    /// supersedes building one from `request.uri`.
    func handleLoad(_ request: DecoderLoadRequest)

    /// Begin or resume playback.
    func handlePlay()

    /// Pause playback.
    func handlePause()

    /// Seek to position in milliseconds.
    func handleSeek(positionMs: Double)

    /// Stop playback and release the current item.
    func handleStop()

    /// Tear down all resources (player, observers, timers).
    func handleDestroy()

    // MARK: - Property Commands

    /// Set playback rate (1.0 = normal speed).
    func handleSetRate(_ rate: Double)

    /// Set volume (0.0–1.0).
    func handleSetVolume(_ volume: Double)

    /// Set muted state.
    func handleSetMuted(_ muted: Bool)

    /// Enable or disable loop replay for the current item.
    func setLoop(_ enabled: Bool)
}
