use std::path::PathBuf;
use gen_file::folder;
use gen_file_database::persistence::delete_db_folder;
use gen_file_database::persistence::init_db_folder;
use gen_file_database_macro::Encapsulate;
use serde::Serialize;
use serde::Deserialize;

#[derive(Clone, Serialize, Deserialize, Encapsulate)]
struct User {
    #[index_key]
    email: String,
    #[index_key]
    username: String,
}

fn test_folder() -> TargetFolder {
    let path: PathBuf = PathBuf::from(format!("./target/test_temp_{}", Uuid::new_v4()));
    let _ = folder::create(&path);
    TargetFolder::from(&path)
}

#[test]
fn test_create_capsule() -> io::Result<()> {
    let folder: TargetFolder = test_folder();
    init_db_folder(&folder)?;
    
    let user: User = User {
        email: "alice@example.com".to_string(),
        username: "alice123".to_string(),
    };

    let result: io::Result<Capsule<User>> = user.create(&folder);
    assert!(result.is_ok(), "create() should succeed");
    let capsule: Capsule<User> = result.unwrap();
    assert_eq!(capsule.inner.email, "alice@example.com");
    assert_eq!(capsule.key, User::file_db_key());

    delete_db_folder(&folder)?;
    Ok(())
}

#[test]
fn test_upsert_capsule() -> io::Result<()> {
    let folder: TargetFolder = test_folder();
    init_db_folder(&folder)?;
    
    let user: User = User {
        email: "bob@example.com".to_string(),
        username: "bobby".to_string(),
    };

    let result: io::Result<Capsule<User>> = user.upsert(&folder);
    assert!(result.is_ok(), "upsert() should succeed");
    let capsule: Capsule<User> = result.unwrap();
    assert_eq!(capsule.inner.username, "bobby");
    assert_eq!(capsule.key, User::file_db_key());

    delete_db_folder(&folder)?;
    Ok(())
}
