use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
#[cfg(feature = "load_extension")]
use std::path::Path;
use std::ptr;
use std::str;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};

use super::ffi;
use super::str_for_sqlite;
use super::{Connection, InterruptHandle, OpenFlags, Result};
use crate::error::{error_from_handle, error_from_sqlite_code, Error};
use crate::raw_statement::RawStatement;
use crate::statement::Statement;
use crate::version::version_number;

pub struct InnerConnection {
    pub db: *mut ffi::sqlite3,
    // It's unsafe to call `sqlite3_close` while another thread is performing
    // a `sqlite3_interrupt`, and vice versa, so we take this mutex during
    // those functions. This protects a copy of the `db` pointer (which is
    // cleared on closing), however the main copy, `db`, is unprotected.
    // Otherwise, a long running query would prevent calling interrupt, as
    // interrupt would only acquire the lock after the query's completion.
    interrupt_lock: Arc<Mutex<*mut ffi::sqlite3>>,
    #[cfg(feature = "hooks")]
    pub free_commit_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
    #[cfg(feature = "hooks")]
    pub free_rollback_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
    #[cfg(feature = "hooks")]
    pub free_update_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
    #[cfg(feature = "hooks")]
    pub progress_handler: Option<Box<dyn FnMut() -> bool + Send>>,
    #[cfg(feature = "hooks")]
    pub authorizer: Option<crate::hooks::BoxedAuthorizer>,
    owned: bool,
}

unsafe impl Send for InnerConnection {}

impl InnerConnection {
    #[allow(clippy::mutex_atomic)]
    #[inline]
    pub unsafe fn new(db: *mut ffi::sqlite3, owned: bool) -> InnerConnection {
        InnerConnection {
            db,
            interrupt_lock: Arc::new(Mutex::new(db)),
            #[cfg(feature = "hooks")]
            free_commit_hook: None,
            #[cfg(feature = "hooks")]
            free_rollback_hook: None,
            #[cfg(feature = "hooks")]
            free_update_hook: None,
            #[cfg(feature = "hooks")]
            progress_handler: None,
            #[cfg(feature = "hooks")]
            authorizer: None,
            owned,
        }
    }

    pub fn open_with_flags(
        c_path: &CStr,
        flags: OpenFlags,
        vfs: Option<&CStr>,
    ) -> Result<InnerConnection> {
        ensure_safe_sqlite_threading_mode()?;

        // Replicate the check for sane open flags from SQLite, because the check in
        // SQLite itself wasn't added until version 3.7.3.
        debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_ONLY.bits, 0x02);
        debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_WRITE.bits, 0x04);
        debug_assert_eq!(
            1 << (OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE).bits,
            0x40
        );
        if (1 << (flags.bits & 0x7)) & 0x46 == 0 {
            return Err(Error::SqliteFailure(
                ffi::Error::new(ffi::SQLITE_MISUSE),
                None,
            ));
        }

        let z_vfs = match vfs {
            Some(c_vfs) => c_vfs.as_ptr(),
            None => ptr::null(),
        };

        unsafe {
            let mut db: *mut ffi::sqlite3 = ptr::null_mut();
            let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), z_vfs);
            if r != ffi::SQLITE_OK {
                let e = if db.is_null() {
                    error_from_sqlite_code(r, Some(c_path.to_string_lossy().to_string()))
                } else {
                    let mut e = error_from_handle(db, r);
                    if let Error::SqliteFailure(
                        ffi::Error {
                            code: ffi::ErrorCode::CannotOpen,
                            ..
                        },
                        Some(msg),
                    ) = e
                    {
                        e = Error::SqliteFailure(
                            ffi::Error::new(r),
                            Some(format!("{}: {}", msg, c_path.to_string_lossy())),
                        );
                    }
                    ffi::sqlite3_close(db);
                    e
                };

                return Err(e);
            }

            // attempt to turn on extended results code; don't fail if we can't.
            ffi::sqlite3_extended_result_codes(db, 1);

            let r = ffi::sqlite3_busy_timeout(db, 5000);
            if r != ffi::SQLITE_OK {
                let e = error_from_handle(db, r);
                ffi::sqlite3_close(db);
                return Err(e);
            }

            Ok(InnerConnection::new(db, true))
        }
    }

    #[inline]
    pub fn db(&self) -> *mut ffi::sqlite3 {
        self.db
    }

    #[inline]
    pub fn decode_result(&self, code: c_int) -> Result<()> {
        unsafe { InnerConnection::decode_result_raw(self.db(), code) }
    }

    #[inline]
    unsafe fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> {
        if code == ffi::SQLITE_OK {
            Ok(())
        } else {
            Err(error_from_handle(db, code))
        }
    }

    #[allow(clippy::mutex_atomic)]
    pub fn close(&mut self) -> Result<()> {
        if self.db.is_null() {
            return Ok(());
        }
        self.remove_hooks();
        let mut shared_handle = self.interrupt_lock.lock().unwrap();
        assert!(
            !shared_handle.is_null(),
            "Bug: Somehow interrupt_lock was cleared before the DB was closed"
        );
        if !self.owned {
            self.db = ptr::null_mut();
            return Ok(());
        }
        unsafe {
            let r = ffi::sqlite3_close(self.db);
            // Need to use _raw because _guard has a reference out, and
            // decode_result takes &mut self.
            let r = InnerConnection::decode_result_raw(self.db, r);
            if r.is_ok() {
                *shared_handle = ptr::null_mut();
                self.db = ptr::null_mut();
            }
            r
        }
    }

    #[inline]
    pub fn get_interrupt_handle(&self) -> InterruptHandle {
        InterruptHandle {
            db_lock: Arc::clone(&self.interrupt_lock),
        }
    }

    #[inline]
    #[cfg(feature = "load_extension")]
    pub unsafe fn enable_load_extension(&mut self, onoff: c_int) -> Result<()> {
        let r = ffi::sqlite3_enable_load_extension(self.db, onoff);
        self.decode_result(r)
    }

    #[cfg(feature = "load_extension")]
    pub unsafe fn load_extension(
        &self,
        dylib_path: &Path,
        entry_point: Option<&str>,
    ) -> Result<()> {
        let dylib_str = super::path_to_cstring(dylib_path)?;
        let mut errmsg: *mut c_char = ptr::null_mut();
        let r = if let Some(entry_point) = entry_point {
            let c_entry = crate::str_to_cstring(entry_point)?;
            ffi::sqlite3_load_extension(self.db, dylib_str.as_ptr(), c_entry.as_ptr(), &mut errmsg)
        } else {
            ffi::sqlite3_load_extension(self.db, dylib_str.as_ptr(), ptr::null(), &mut errmsg)
        };
        if r == ffi::SQLITE_OK {
            Ok(())
        } else {
            let message = super::errmsg_to_string(errmsg);
            ffi::sqlite3_free(errmsg.cast::<::std::os::raw::c_void>());
            Err(error_from_sqlite_code(r, Some(message)))
        }
    }

    #[inline]
    pub fn last_insert_rowid(&self) -> i64 {
        unsafe { ffi::sqlite3_last_insert_rowid(self.db()) }
    }

    pub fn prepare<'a>(&mut self, conn: &'a Connection, sql: &str) -> Result<Statement<'a>> {
        let mut c_stmt = ptr::null_mut();
        let (c_sql, len, _) = str_for_sqlite(sql.as_bytes())?;
        let mut c_tail = ptr::null();
        #[cfg(not(feature = "unlock_notify"))]
        let r = unsafe {
            ffi::sqlite3_prepare_v2(
                self.db(),
                c_sql,
                len,
                &mut c_stmt as *mut *mut ffi::sqlite3_stmt,
                &mut c_tail as *mut *const c_char,
            )
        };
        #[cfg(feature = "unlock_notify")]
        let r = unsafe {
            use crate::unlock_notify;
            let mut rc;
            loop {
                rc = ffi::sqlite3_prepare_v2(
                    self.db(),
                    c_sql,
                    len,
                    &mut c_stmt as *mut *mut ffi::sqlite3_stmt,
                    &mut c_tail as *mut *const c_char,
                );
                if !unlock_notify::is_locked(self.db, rc) {
                    break;
                }
                rc = unlock_notify::wait_for_unlock_notify(self.db);
                if rc != ffi::SQLITE_OK {
                    break;
                }
            }
            rc
        };
        // If there is an error, *ppStmt is set to NULL.
        self.decode_result(r)?;
        // If the input text contains no SQL (if the input is an empty string or a
        // comment) then *ppStmt is set to NULL.
        let c_stmt: *mut ffi::sqlite3_stmt = c_stmt;
        let c_tail: *const c_char = c_tail;
        let tail = if c_tail.is_null() {
            0
        } else {
            let n = (c_tail as isize) - (c_sql as isize);
            if n <= 0 || n >= len as isize {
                0
            } else {
                n as usize
            }
        };
        Ok(Statement::new(conn, unsafe {
            RawStatement::new(c_stmt, tail)
        }))
    }

    #[inline]
    pub fn changes(&self) -> usize {
        unsafe { ffi::sqlite3_changes(self.db()) as usize }
    }

    #[inline]
    pub fn is_autocommit(&self) -> bool {
        unsafe { ffi::sqlite3_get_autocommit(self.db()) != 0 }
    }

    #[cfg(feature = "modern_sqlite")] // 3.8.6
    pub fn is_busy(&self) -> bool {
        let db = self.db();
        unsafe {
            let mut stmt = ffi::sqlite3_next_stmt(db, ptr::null_mut());
            while !stmt.is_null() {
                if ffi::sqlite3_stmt_busy(stmt) != 0 {
                    return true;
                }
                stmt = ffi::sqlite3_next_stmt(db, stmt);
            }
        }
        false
    }

    #[cfg(feature = "modern_sqlite")] // 3.10.0
    pub fn cache_flush(&mut self) -> Result<()> {
        crate::error::check(unsafe { ffi::sqlite3_db_cacheflush(self.db()) })
    }

    #[cfg(not(feature = "hooks"))]
    #[inline]
    fn remove_hooks(&mut self) {}
}

impl Drop for InnerConnection {
    #[allow(unused_must_use)]
    #[inline]
    fn drop(&mut self) {
        use std::thread::panicking;

        if let Err(e) = self.close() {
            if panicking() {
                eprintln!("Error while closing SQLite connection: {:?}", e);
            } else {
                panic!("Error while closing SQLite connection: {:?}", e);
            }
        }
    }
}

#[cfg(not(any(target_arch = "wasm32")))]
static SQLITE_INIT: std::sync::Once = std::sync::Once::new();

pub static BYPASS_SQLITE_INIT: AtomicBool = AtomicBool::new(false);

// threading mode checks are not necessary (and do not work) on target
// platforms that do not have threading (such as webassembly)
#[cfg(any(target_arch = "wasm32"))]
fn ensure_safe_sqlite_threading_mode() -> Result<()> {
    Ok(())
}

#[cfg(not(any(target_arch = "wasm32")))]
fn ensure_safe_sqlite_threading_mode() -> Result<()> {
    // Ensure SQLite was compiled in thredsafe mode.
    if unsafe { ffi::sqlite3_threadsafe() == 0 } {
        return Err(Error::SqliteSingleThreadedMode);
    }

    // Now we know SQLite is _capable_ of being in Multi-thread of Serialized mode,
    // but it's possible someone configured it to be in Single-thread mode
    // before calling into us. That would mean we're exposing an unsafe API via
    // a safe one (in Rust terminology), which is no good. We have two options
    // to protect against this, depending on the version of SQLite we're linked
    // with:
    //
    // 1. If we're on 3.7.0 or later, we can ask SQLite for a mutex and check for
    //    the magic value 8. This isn't documented, but it's what SQLite
    //    returns for its mutex allocation function in Single-thread mode.
    // 2. If we're prior to SQLite 3.7.0, AFAIK there's no way to check the
    //    threading mode. The check we perform for >= 3.7.0 will segfault.
    //    Instead, we insist on being able to call sqlite3_config and
    //    sqlite3_initialize ourself, ensuring we know the threading
    //    mode. This will fail if someone else has already initialized SQLite
    //    even if they initialized it safely. That's not ideal either, which is
    //    why we expose bypass_sqlite_initialization    above.
    if version_number() >= 3_007_000 {
        const SQLITE_SINGLETHREADED_MUTEX_MAGIC: usize = 8;
        let is_singlethreaded = unsafe {
            let mutex_ptr = ffi::sqlite3_mutex_alloc(0);
            let is_singlethreaded = mutex_ptr as usize == SQLITE_SINGLETHREADED_MUTEX_MAGIC;
            ffi::sqlite3_mutex_free(mutex_ptr);
            is_singlethreaded
        };
        if is_singlethreaded {
            Err(Error::SqliteSingleThreadedMode)
        } else {
            Ok(())
        }
    } else {
        SQLITE_INIT.call_once(|| {
            if BYPASS_SQLITE_INIT.load(Ordering::Relaxed) {
                return;
            }

            unsafe {
                assert!(ffi::sqlite3_config(ffi::SQLITE_CONFIG_MULTITHREAD) == ffi::SQLITE_OK && ffi::sqlite3_initialize() == ffi::SQLITE_OK,
                        "Could not ensure safe initialization of SQLite.\n\
                         To fix this, either:\n\
                         * Upgrade SQLite to at least version 3.7.0\n\
                         * Ensure that SQLite has been initialized in Multi-thread or Serialized mode and call\n\
                           rusqlite::bypass_sqlite_initialization() prior to your first connection attempt."
                    );
            }
        });
        Ok(())
    }
}
