mod testprotocol;
mod testsupport;

use crate::testprotocol::acme::user::v1::{Account, Bucket};
use crate::testsupport::get_session_store;
use pbbson::Model;
use saas_rs_sdk::bson::doc;
use saas_rs_sdk::storage::session_store::FindOptions;
use std::time::Duration;

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn can_find_many_with_filter() {
    let session_store = get_session_store!();

    // Create a few accounts
    let mut account_1 = Account {
        email: Some(format!("{}@foo.bar", xid::new())),
        ..Default::default()
    };
    let ttl = Some(Duration::from_secs(10));
    account_1 = session_store
        .create(Bucket::Accounts, Model::try_from(&account_1).unwrap(), ttl)
        .await
        .expect("Expected to be able to create access token")
        .try_into()
        .unwrap();
    let mut account_2 = Account {
        email: Some(format!("{}@foo.bar", xid::new())),
        ..Default::default()
    };
    let ttl = Some(Duration::from_secs(10));
    account_2 = session_store
        .create(Bucket::Accounts, Model::try_from(&account_2).unwrap(), ttl)
        .await
        .expect("Expected to be able to create access token")
        .try_into()
        .unwrap();

    // Find Many
    let accounts: Vec<_> = session_store
        .find_many(Bucket::Accounts, FindOptions::default())
        .await
        .expect("Expected to be able to find newly created accounts")
        .into_iter()
        .map(|model| model.try_into().unwrap())
        .collect();
    assert!(accounts.contains(&account_1));
    assert!(accounts.contains(&account_2));

    // Find Many by ID
    let accounts: Vec<Account> = session_store
        .find_many(
            Bucket::Accounts,
            FindOptions::new().with_filter(Model::from(doc! {"id": &account_2.id})),
        )
        .await
        .expect("Expected to be able to find newly created account by id")
        .into_iter()
        .map(|model| model.try_into().unwrap())
        .collect();
    assert_eq!(accounts.len(), 1);
    let first_account = accounts.first().expect("Expected to be able to find account by id");
    assert_eq!(first_account.id, account_2.id);

    // Find Many by email
    let accounts: Vec<Account> = session_store
        .find_many(
            Bucket::Accounts,
            FindOptions::new().with_filter(Model::from(doc! {"email": &account_2.email})),
        )
        .await
        .expect("Expected to be able to find newly created account by email")
        .into_iter()
        .map(|model| model.try_into().unwrap())
        .collect();
    assert_eq!(accounts.len(), 1);
    let first_account = accounts.first().expect("Expected to be able to find account by email");
    assert_eq!(first_account.id, account_2.id);
}
