use super::Error;
use async_trait::async_trait;
use pbbson::Model;
use std::time::Duration;

#[async_trait]
pub trait SessionStore<B: ToString>: Sync + Send {
    async fn create(&self, bucket: B, model: Model, maybe_expires: Option<Duration>) -> Result<Model, Error>;
    async fn delete(&self, bucket: B, id: &str) -> Result<(), Error>;
    async fn find(&self, bucket: B, id: &str) -> Result<Model, Error>;
    async fn find_many(&self, bucket: B, options: FindOptions) -> Result<Vec<Model>, Error>;
    async fn update(&self, bucket: B, model: Model, maybe_expires: Option<Duration>) -> Result<Model, Error>;
}

#[derive(Clone, Debug, Default)]
pub struct FindOptions {
    pub filter: Model,
    pub ordering: Option<Model>,
}

impl FindOptions {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn with_filter(&self, filter: Model) -> Self {
        Self {
            filter,
            ordering: self.ordering.clone(),
        }
    }

    pub fn with_ordering(&self, ordering: Option<Model>) -> Self {
        Self {
            filter: self.filter.clone(),
            ordering,
        }
    }
}
