use super::{
    MongodbConfigStore,
    serde::{transform_from_mongo, transform_to_mongo},
};
use crate::storage::Error;
use futures::TryStreamExt;
use mongodb::{Collection, bson::Document};
use pbbson::Model;

pub async fn find_many<B: Clone + Send + Sync + ToString>(
    this: &MongodbConfigStore<B>,
    bucket: B,
    filter: Model,
    maybe_ordering: Option<Model>,
) -> Result<Vec<Model>, Error> {
    let coll: Collection<Document> = this.db.collection(&bucket.to_string());
    let filter = transform_to_mongo(filter)?;
    let mut find_future = coll.find(filter.into());
    if let Some(ordering) = maybe_ordering {
        let ordering = transform_to_mongo(ordering)?;
        find_future = find_future.sort(ordering.into());
    }
    let mut cursor = find_future.await.map_err(|e| Error::internal(e.to_string()))?;
    let mut models = vec![];
    while let Some(document) = cursor.try_next().await.map_err(|e| Error::internal(e.to_string()))? {
        models.push(transform_from_mongo(document.into())?);
    }
    Ok(models)
}
