use std::pin::Pin;
use crate::Exception;

/// Object storage abstraction definition
pub trait ObjectStorage {

    /// 对象存储中，每个对象的元数据内容
    type ObjectMeta;

    /// 列举指定前缀开头的所有对象元数据
    fn list<'a>(&'a self, object_key_prefix: &'a str) -> Pin<Box<dyn Future<Output = Result<Vec<Self::ObjectMeta>, Exception>> + Send + 'a>>;

    /// 上传对象
    fn upload_bytes<'a>(&'a self, object_key: &'a str, data: Vec<u8>) -> Pin<Box<dyn Future<Output = Result<(), Exception>> + Send + 'a>>;

    /// 上传文件
    fn upload_file<'a>(&'a self, object_key: &'a str, file_path: &'a str) -> Pin<Box<dyn Future<Output = Result<(), Exception>> + Send + 'a>>;

    /// 下载对象，方法内部会构造http请求：
    fn download_bytes<'a>(&'a self, object_key: &'a str) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, Exception>> + Send + 'a>>;


    /// 下载文件，并指定本地保存用的文件路径
    ///
    /// # 参数
    ///
    /// `overwrite` - 是否覆盖，true，当文件存在时，覆盖文件，false，当文件存在时，不覆盖文件
    ///
    fn download_file<'a>(&'a self, object_key: &'a str, file_path: &'a str, overwrite: bool) -> Pin<Box<dyn Future<Output = Result<(), Exception>> + Send + 'a>>;

    fn url_sign(&self, object_key: &str) -> Result<String, Exception>;
}

// pub struct Mmm;
// impl ObjectStorage for Mmm {
//     type ObjectMeta = String;
//
//     fn list<'a>(&'a self, object_key_prefix: &'a str) -> Pin<Box<dyn Future<Output=Result<Vec<Self::ObjectMeta>, Exception>> + Send + 'a>> {
//
//         let fut = async {
//             let s = "hello".to_string();
//             Ok(vec![s])
//         };
//         Box::pin(fut)
//     }
//
// }