use thiserror::Error;

#[derive(Error, Debug)]
pub enum CodecError {
    #[error("Failed to initialize codec: {0}")]
    Init(String),
    #[error("Encoding failed: {0}")]
    Encode(String),
    #[error("Decoding failed: {0}")]
    Decode(String),
}

pub trait AudioEncoder: Send {
    /// Encodes raw PCM samples into compressed bytes.
    fn encode(&mut self, pcm: &[i16]) -> Result<Vec<u8>, CodecError>;
}

pub trait AudioDecoder: Send {
    /// Decodes compressed bytes back into raw PCM samples.
    /// If `compressed` is `None` (or `Some(&[])`), it indicates packet loss,
    /// enabling the decoder to perform packet loss concealment (PLC).
    fn decode(&mut self, compressed: Option<&[u8]>) -> Result<Vec<i16>, CodecError>;

    /// Reconstructs the previous lost frame from the next packet's in-band FEC.
    fn decode_fec(&mut self, next_payload: &[u8]) -> Result<Vec<i16>, CodecError>;
}

pub mod opus_impl;
