use bytes::Bytes;
use futures::TryStreamExt;
use object_store::{ObjectStore, path::Path};
use std::sync::Arc;

pub async fn put(store: &Arc<dyn ObjectStore>, key: &str, data: Bytes) -> Result<(), String> {
    let path = Path::from(key);
    store.put(&path, data.into()).await.map_err(|e| e.to_string())?;
    Ok(())
}

pub async fn get(store: &Arc<dyn ObjectStore>, key: &str) -> Result<Bytes, String> {
    let path = Path::from(key);
    let result = store.get(&path).await.map_err(|e| e.to_string())?;
    let bytes = result.bytes().await.map_err(|e| e.to_string())?;
    Ok(bytes)
}

pub async fn delete(store: &Arc<dyn ObjectStore>, key: &str) -> Result<(), String> {
    let path = Path::from(key);
    store.delete(&path).await.map_err(|e| e.to_string())?;
    Ok(())
}

pub async fn list(store: &Arc<dyn ObjectStore>, prefix: Option<&str>) -> Result<Vec<String>, String> {
    let prefix_path = prefix.map(Path::from);
    let stream = store.list(prefix_path.as_ref());
    let items: Vec<_> = stream.try_collect().await.map_err(|e| e.to_string())?;
    Ok(items.into_iter().map(|m| m.location.to_string()).collect())
}
