use crate::*;

/// Creates a new chunk of audio data.
pub trait ChunkFactory: Send {
    fn create_chunk(&mut self) -> Result<std::sync::Arc<AudioChunk>>;
}

impl<F> ChunkFactory for F
where
    F: FnMut() -> Result<std::sync::Arc<AudioChunk>> + Send,
{
    fn create_chunk(&mut self) -> Result<std::sync::Arc<AudioChunk>> {
        self()
    }
}

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

    pub struct MockFactory {
        chunks: Vec<std::sync::Arc<AudioChunk>>,
    }

    impl MockFactory {
        pub fn new(chunks: Vec<std::sync::Arc<AudioChunk>>) -> Self {
            Self { chunks }
        }
    }

    impl ChunkFactory for MockFactory {
        fn create_chunk(&mut self) -> Result<std::sync::Arc<AudioChunk>> {
            if let Some(chunk) = self.chunks.pop() {
                Ok(chunk)
            } else {
                Err(LooperError::ChunkAllocation(std::panic::Location::caller()))
            }
        }
    }
}
