Skip to content
use rand::RngCore;
use rand::rngs::OsRng;
use std::sync::atomic::{AtomicBool, Ordering};

use crate::db::Database;

pub mod handlers;

pub fn generate_token() -> String {
    let mut bytes = [0u8; 32];
    OsRng.fill_bytes(&mut bytes);
    hex::encode(bytes)
}

pub struct NotesContext {
    db: Database,
    initialized: AtomicBool,
}

impl NotesContext {
    pub fn new(db: Database) -> Self {
        Self {
            db,
            initialized: AtomicBool::new(false),
        }
    }

    pub fn db(&self) -> &Database {
        &self.db
    }

    pub fn set_initialized(&self) {
        self.initialized.store(true, Ordering::SeqCst);
    }

    pub async fn create_session(&self, username: String) -> Result<String, String> {
        let db = self.db();
        let token = generate_token();
        db.create_token(&token, &username).await?;
        if let Err(e) = db.cleanup_expired_tokens().await {
            log::warn!("Failed to cleanup expired tokens: {e}");
        }
        Ok(token)
    }

    pub async fn validate_token(&self, token: &str) -> Option<String> {
        let db = self.db();
        db.get_username_by_token(token).await.ok().flatten()
    }

    pub async fn invalidate_token(&self, token: &str) -> Result<(), String> {
        let db = self.db();
        db.delete_token(token).await
    }
}