//! Integration test that drives `ChanoraSession::init_storage` end
//! to end against a fresh temp directory and verifies the MVP
//! hardening: identity round-trips through the encrypted file
//! envelope, and bookmark server passwords are stored as
//! `password_blob` rather than the legacy plain `password` column.
//!
//! Forces the `CHANORA_DISABLE_KEYRING` toggle so the test runs
//! without a D-Bus session.

use std::env;
use std::path::PathBuf;
use std::process;
use std::time::{SystemTime, UNIX_EPOCH};

#[tokio::test]
async fn init_storage_encrypts_identity_and_bookmark_passwords() {
    env::set_var("CHANORA_DISABLE_KEYRING", "1");

    let tmp = mktemp("chanora_core_init_storage_test");
    let session = chanora_core::ChanoraSession::new();
    session.init_storage(&tmp).await.unwrap();

    // No identity yet.
    let id_path = tmp.join("identity.tskey");
    assert!(!id_path.exists(), "identity should not exist before first connect");

    // A bookmark with a password lands as an encrypted blob.
    let id = session
        .add_bookmark(chanora_core::Bookmark {
            id: 0,
            display_name: "test".to_string(),
            host: "h".to_string(),
            nickname: "n".to_string(),
            password: Some("hunter2".to_string()),
        })
        .await
        .unwrap();
    assert!(id > 0);

    let rows = session.list_bookmarks().await.unwrap();
    assert_eq!(rows.len(), 1);
    assert_eq!(rows[0].password.as_deref(), Some("hunter2"));

    // Inspect the SQLite file directly to prove the plain column
    // is null and the blob does not contain the plaintext.
    let conn = rusqlite::Connection::open(tmp.join("chanora.db")).unwrap();
    let (plain, blob): (Option<String>, Option<Vec<u8>>) = conn
        .query_row(
            "SELECT password, password_blob FROM bookmarks WHERE id=?1",
            rusqlite::params![id],
            |r| Ok((r.get(0)?, r.get(1)?)),
        )
        .unwrap();
    assert!(plain.is_none(), "plaintext password column should be NULL");
    let blob = blob.expect("password_blob should be populated");
    assert!(
        !blob.windows(7).any(|w| w == b"hunter2"),
        "blob must not contain plaintext"
    );

    let _ = std::fs::remove_dir_all(&tmp);
}

fn mktemp(label: &str) -> PathBuf {
    let nanos = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos();
    let p = env::temp_dir()
        .join(label)
        .join(format!("{}-{nanos}", process::id()));
    std::fs::create_dir_all(&p).unwrap();
    p
}
