//! Configure database connections

use std::os::raw::c_int;

use crate::error::check;
use crate::ffi;
use crate::{Connection, Result};

/// Database Connection Configuration Options
/// See [Database Connection Configuration Options](https://sqlite.org/c3ref/c_dbconfig_enable_fkey.html) for details.
#[repr(i32)]
#[allow(non_snake_case, non_camel_case_types)]
#[non_exhaustive]
#[allow(clippy::upper_case_acronyms)]
pub enum DbConfig {
    //SQLITE_DBCONFIG_MAINDBNAME = 1000, /* const char* */
    //SQLITE_DBCONFIG_LOOKASIDE = 1001,  /* void* int int */
    /// Enable or disable the enforcement of foreign key constraints.
    SQLITE_DBCONFIG_ENABLE_FKEY = 1002,
    /// Enable or disable triggers.
    SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003,
    /// Enable or disable the fts3_tokenizer() function which is part of the
    /// FTS3 full-text search engine extension.
    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004, // 3.12.0
    //SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005,
    /// In WAL mode, enable or disable the checkpoint operation before closing
    /// the connection.
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006, // 3.16.2
    /// Activates or deactivates the query planner stability guarantee (QPSG).
    SQLITE_DBCONFIG_ENABLE_QPSG = 1007, // 3.20.0
    /// Includes or excludes output for any operations performed by trigger
    /// programs from the output of EXPLAIN QUERY PLAN commands.
    SQLITE_DBCONFIG_TRIGGER_EQP = 1008, // 3.22.0
    /// Activates or deactivates the "reset" flag for a database connection.
    /// Run VACUUM with this flag set to reset the database.
    SQLITE_DBCONFIG_RESET_DATABASE = 1009, // 3.24.0
    /// Activates or deactivates the "defensive" flag for a database connection.
    SQLITE_DBCONFIG_DEFENSIVE = 1010, // 3.26.0
    /// Activates or deactivates the "writable_schema" flag.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1011, // 3.28.0
    /// Activates or deactivates the legacy behavior of the ALTER TABLE RENAME
    /// command.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1012, // 3.29
    /// Activates or deactivates the legacy double-quoted string literal
    /// misfeature for DML statements only.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_DQS_DML = 1013, // 3.29.0
    /// Activates or deactivates the legacy double-quoted string literal
    /// misfeature for DDL statements.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_DQS_DDL = 1014, // 3.29.0
    /// Enable or disable views.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_ENABLE_VIEW = 1015, // 3.30.0
    /// Activates or deactivates the legacy file format flag.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1016, // 3.31.0
    /// Tells SQLite to assume that database schemas (the contents of the
    /// sqlite_master tables) are untainted by malicious content.
    #[cfg(feature = "modern_sqlite")]
    SQLITE_DBCONFIG_TRUSTED_SCHEMA = 1017, // 3.31.0
}

impl Connection {
    /// Returns the current value of a `config`.
    ///
    /// - `SQLITE_DBCONFIG_ENABLE_FKEY`: return `false` or `true` to indicate
    ///   whether FK enforcement is off or on
    /// - `SQLITE_DBCONFIG_ENABLE_TRIGGER`: return `false` or `true` to indicate
    ///   whether triggers are disabled or enabled
    /// - `SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER`: return `false` or `true` to
    ///   indicate whether `fts3_tokenizer` are disabled or enabled
    /// - `SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE`: return `false` to indicate
    ///   checkpoints-on-close are not disabled or `true` if they are
    /// - `SQLITE_DBCONFIG_ENABLE_QPSG`: return `false` or `true` to indicate
    ///   whether the QPSG is disabled or enabled
    /// - `SQLITE_DBCONFIG_TRIGGER_EQP`: return `false` to indicate
    ///   output-for-trigger are not disabled or `true` if it is
    #[inline]
    pub fn db_config(&self, config: DbConfig) -> Result<bool> {
        let c = self.db.borrow();
        unsafe {
            let mut val = 0;
            check(ffi::sqlite3_db_config(
                c.db(),
                config as c_int,
                -1,
                &mut val,
            ))?;
            Ok(val != 0)
        }
    }

    /// Make configuration changes to a database connection
    ///
    /// - `SQLITE_DBCONFIG_ENABLE_FKEY`: `false` to disable FK enforcement,
    ///   `true` to enable FK enforcement
    /// - `SQLITE_DBCONFIG_ENABLE_TRIGGER`: `false` to disable triggers, `true`
    ///   to enable triggers
    /// - `SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER`: `false` to disable
    ///   `fts3_tokenizer()`, `true` to enable `fts3_tokenizer()`
    /// - `SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE`: `false` (the default) to enable
    ///   checkpoints-on-close, `true` to disable them
    /// - `SQLITE_DBCONFIG_ENABLE_QPSG`: `false` to disable the QPSG, `true` to
    ///   enable QPSG
    /// - `SQLITE_DBCONFIG_TRIGGER_EQP`: `false` to disable output for trigger
    ///   programs, `true` to enable it
    #[inline]
    pub fn set_db_config(&self, config: DbConfig, new_val: bool) -> Result<bool> {
        let c = self.db.borrow_mut();
        unsafe {
            let mut val = 0;
            check(ffi::sqlite3_db_config(
                c.db(),
                config as c_int,
                if new_val { 1 } else { 0 },
                &mut val,
            ))?;
            Ok(val != 0)
        }
    }
}

#[cfg(test)]
mod test {
    use super::DbConfig;
    use crate::{Connection, Result};

    #[test]
    fn test_db_config() -> Result<()> {
        let db = Connection::open_in_memory()?;

        let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY)?;
        assert_eq!(
            db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY, opposite),
            Ok(opposite)
        );
        assert_eq!(
            db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY),
            Ok(opposite)
        );

        let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER)?;
        assert_eq!(
            db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER, opposite),
            Ok(opposite)
        );
        assert_eq!(
            db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER),
            Ok(opposite)
        );
        Ok(())
    }
}
