use super::MemoryConfigStore;
use crate::storage::Error;
use crate::storage::config_store::FindOptions;
use pbbson::Model;

pub(crate) async fn perform<B: Clone + Send + Sync + ToString>(
    this: &MemoryConfigStore<B>,
    bucket: B,
    options: FindOptions,
) -> Result<Vec<Model>, Error> {
    let doc_holder = this.doc_holder(&bucket)?;
    let docs = doc_holder
        .docs
        .lock()
        .map_err(|e| Error::failed_precondition(e.to_string()))?;
    let mut models: Vec<Model> = docs.values().cloned().collect();
    if let Some(projection) = options.projection {
        for model in models.iter_mut() {
            for key in model.clone().keys() {
                if projection.get_i32(key) == Ok(0) {
                    model.remove(key);
                }
            }
        }
    }
    if let (Some(offset), _) = options.pagination {
        models.drain(0..offset as usize);
    }
    if let (_, Some(limit)) = options.pagination {
        models.truncate(limit as usize);
    }
    Ok(models)
}
