//! Minimal `LocalDatabaseRepository` stand-in (SDD-077). Holds *non-secret*
//! state only — bookmarks, in this PoC. Used by the audit tests to prove
//! SS-AUD-001 / SS-AUD-002: a secret stored via the secure-storage
//! adapter never appears in the SQLite file.

use std::path::Path;

use rusqlite::{params, Connection};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum LocalDbError {
    #[error("sqlite error: {0}")]
    Sqlite(#[from] rusqlite::Error),
}

pub struct LocalDatabaseRepository {
    conn: Connection,
}

impl LocalDatabaseRepository {
    pub fn open(path: &Path) -> Result<Self, LocalDbError> {
        let conn = Connection::open(path)?;
        conn.execute_batch(
            "CREATE TABLE IF NOT EXISTS bookmarks (
                 id            INTEGER PRIMARY KEY AUTOINCREMENT,
                 server_name   TEXT NOT NULL,
                 server_host   TEXT NOT NULL,
                 identity_ref  TEXT NOT NULL
             );",
        )?;
        Ok(Self { conn })
    }

    /// Insert a bookmark. `identity_ref` is a *reference* (e.g. a stable
    /// secret name like `identity.primary`), **not** the secret itself.
    /// This is the SAD-067 separation in action.
    pub fn insert_bookmark(
        &self,
        server_name: &str,
        server_host: &str,
        identity_ref: &str,
    ) -> Result<i64, LocalDbError> {
        self.conn.execute(
            "INSERT INTO bookmarks (server_name, server_host, identity_ref) VALUES (?1, ?2, ?3)",
            params![server_name, server_host, identity_ref],
        )?;
        Ok(self.conn.last_insert_rowid())
    }

    /// For the audit: read the raw bytes of the underlying SQLite file
    /// so a test can grep for forbidden plaintext (SS-AUD-001).
    pub fn raw_db_bytes(path: &Path) -> std::io::Result<Vec<u8>> {
        std::fs::read(path)
    }
}
