//! Engine-abstraction trait for speech-to-text backends.
//!
//! Replaces the previous `SpeechBackend` enum so new backends
//! (Moonshine, whisper-rs forks, cloud ASR shims, Windows non-AVX2
//! fallbacks) can drop in without adding a match arm in `LocalEngine`.
//!
//! Concrete implementers today: `SpeechModelAdapter` (wraps any
//! `transcribe-rs` model, currently used for Parakeet) and — behind the
//! `whisper` feature — `WhisperRsBackend` (direct whisper-rs, the only
//! path that pipes `initial_prompt`).

use kon_core::error::Result;
use kon_core::types::{Segment, TranscriptionOptions};

/// Static capabilities a `Transcriber` advertises to callers.
///
/// `sample_rate` is load-bearing for the progressive WAV writer (#19)
/// which writes live capture samples to disk at the transcriber's
/// native rate. `supports_initial_prompt` lets the Settings surface
/// hide the initial-prompt field for backends that ignore it (Parakeet
/// today).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TranscriberCapabilities {
    pub sample_rate: u32,
    pub channels: u16,
    pub supports_initial_prompt: bool,
}

/// Unified interface for speech-to-text backends.
///
/// `Send` is a supertrait so `Box<dyn Transcriber + Send>` travels
/// across `spawn_blocking` boundaries without a per-site bound. All
/// inference is synchronous — async callers wrap a `tokio::spawn_blocking`
/// around `transcribe_sync`.
pub trait Transcriber: Send {
    fn capabilities(&self) -> TranscriberCapabilities;

    /// Synchronously transcribe 16 kHz mono f32 PCM (or whatever the
    /// backend's `capabilities().sample_rate` declares). `&mut self` so
    /// backends that keep per-call scratch state (whisper-rs's
    /// `WhisperState`, Parakeet's decoder buffers) can mutate them
    /// without interior-mutability gymnastics.
    fn transcribe_sync(
        &mut self,
        samples: &[f32],
        options: &TranscriptionOptions,
    ) -> Result<Vec<Segment>>;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn transcriber_trait_is_object_safe() {
        // Compile-time witness: if the trait stops being object-safe
        // (e.g. someone adds a generic method or a Self-returning
        // method) this declaration fails to build. No runtime work.
        let _: Option<Box<dyn Transcriber + Send>> = None;
    }
}
