use super::ConnectionState;
use crate::{error::Error, SqliteConnection, SqliteError};
use libsqlite3_sys::{
    sqlite3_deserialize, sqlite3_free, sqlite3_malloc64, sqlite3_serialize,
    SQLITE_DESERIALIZE_FREEONCLOSE, SQLITE_DESERIALIZE_READONLY, SQLITE_DESERIALIZE_RESIZEABLE,
    SQLITE_NOMEM, SQLITE_OK,
};
use std::ffi::c_char;
use std::fmt::Debug;
use std::{
    ops::{Deref, DerefMut},
    ptr,
    ptr::NonNull,
};

impl SqliteConnection {
    /// Serialize the given SQLite database schema using [`sqlite3_serialize()`].
    ///
    /// The returned buffer is a SQLite managed allocation containing the equivalent data
    /// as writing the database to disk. It is freed on-drop.
    ///
    /// To serialize the primary, unqualified schema (`main`), pass `None` for the schema name.
    ///
    /// # Errors
    /// * [`Error::InvalidArgument`] if the schema name contains a zero/NUL byte (`\0`).
    /// * [`Error::Database`] if the schema does not exist or another error occurs.
    ///
    /// [`sqlite3_serialize()`]: https://sqlite.org/c3ref/serialize.html
    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite-deserialize")))]
    pub async fn serialize(&mut self, schema: Option<&str>) -> Result<SqliteOwnedBuf, Error> {
        let schema = schema.map(SchemaName::try_from).transpose()?;

        self.worker.serialize(schema).await
    }

    /// Deserialize a SQLite database from a buffer into the specified schema using [`sqlite3_deserialize()`].
    ///
    /// The given schema will be disconnected and re-connected as an in-memory database
    /// backed by `data`, which should be the serialized form of a database previously returned
    /// by a call to [`Self::serialize()`], documented as being equivalent to
    /// the contents of the database file on disk.
    ///
    /// An error will be returned if a schema with the given name is not already attached.
    /// You can use `ATTACH ':memory' as "<schema name>"` to create an empty schema first.
    ///
    /// Pass `None` to deserialize to the primary, unqualified schema (`main`).
    ///
    /// The SQLite connection will take ownership of `data` and will free it when the connection
    /// is closed or the schema is detached ([`SQLITE_DESERIALIZE_FREEONCLOSE`][deserialize-flags]).
    ///
    /// If `read_only` is `true`, the schema is opened as read-only ([`SQLITE_DESERIALIZE_READONLY`][deserialize-flags]).
    /// If `false`, the schema is marked as resizable ([`SQLITE_DESERIALIZE_RESIZABLE`][deserialize-flags]).
    ///
    /// If the database is in WAL mode, an error is returned.
    /// See [`sqlite3_deserialize()`] for details.
    ///
    /// # Errors
    /// * [`Error::InvalidArgument`] if the schema name contains a zero/NUL byte (`\0`).
    /// * [`Error::Database`] if an error occurs during deserialization.
    ///
    /// [`sqlite3_deserialize()`]: https://sqlite.org/c3ref/deserialize.html
    /// [deserialize-flags]: https://sqlite.org/c3ref/c_deserialize_freeonclose.html
    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite-deserialize")))]
    pub async fn deserialize(
        &mut self,
        schema: Option<&str>,
        data: SqliteOwnedBuf,
        read_only: bool,
    ) -> Result<(), Error> {
        let schema = schema.map(SchemaName::try_from).transpose()?;

        self.worker.deserialize(schema, data, read_only).await
    }
}

pub(crate) fn serialize(
    conn: &mut ConnectionState,
    schema: Option<SchemaName>,
) -> Result<SqliteOwnedBuf, Error> {
    let mut size = 0;

    let buf = unsafe {
        let ptr = sqlite3_serialize(
            conn.handle.as_ptr(),
            schema.as_ref().map_or(ptr::null(), SchemaName::as_ptr),
            &mut size,
            0,
        );

        // looking at the source, `sqlite3_serialize` actually sets `size = -1` on error:
        // https://github.com/sqlite/sqlite/blob/da5f81387843f92652128087a8f8ecef0b79461d/src/memdb.c#L776
        usize::try_from(size)
            .ok()
            .and_then(|size| SqliteOwnedBuf::from_raw(ptr, size))
    };

    if let Some(buf) = buf {
        return Ok(buf);
    }

    if let Some(error) = conn.handle.last_error() {
        return Err(error.into());
    }

    if size > 0 {
        // If `size` is positive but `sqlite3_serialize` still returned NULL,
        // the most likely culprit is an out-of-memory condition.
        return Err(SqliteError::from_code(SQLITE_NOMEM).into());
    }

    // Otherwise, the schema was probably not found.
    // We return the equivalent error as when you try to execute `PRAGMA <schema>.page_count`
    // against a non-existent schema.
    Err(SqliteError::generic(format!(
        "database {} does not exist",
        schema.as_ref().map_or("main", SchemaName::as_str)
    ))
    .into())
}

pub(crate) fn deserialize(
    conn: &mut ConnectionState,
    schema: Option<SchemaName>,
    data: SqliteOwnedBuf,
    read_only: bool,
) -> Result<(), Error> {
    // SQLITE_DESERIALIZE_FREEONCLOSE causes SQLite to take ownership of the buffer
    let mut flags = SQLITE_DESERIALIZE_FREEONCLOSE;
    if read_only {
        flags |= SQLITE_DESERIALIZE_READONLY;
    } else {
        flags |= SQLITE_DESERIALIZE_RESIZEABLE;
    }

    let (buf, size) = data.into_raw();

    let rc = unsafe {
        sqlite3_deserialize(
            conn.handle.as_ptr(),
            schema.as_ref().map_or(ptr::null(), SchemaName::as_ptr),
            buf,
            i64::try_from(size).unwrap(),
            i64::try_from(size).unwrap(),
            flags,
        )
    };

    match rc {
        SQLITE_OK => Ok(()),
        SQLITE_NOMEM => Err(SqliteError::from_code(SQLITE_NOMEM).into()),
        // SQLite unfortunately doesn't set any specific message for deserialization errors.
        _ => Err(SqliteError::generic("an error occurred during deserialization").into()),
    }
}

/// Memory buffer owned and allocated by SQLite. Freed on drop.
///
/// Intended primarily for use with [`SqliteConnection::serialize()`] and [`SqliteConnection::deserialize()`].
///
/// Can be created from `&[u8]` using the `TryFrom` impl. The slice must not be empty.
#[derive(Debug)]
pub struct SqliteOwnedBuf {
    ptr: NonNull<u8>,
    size: usize,
}

unsafe impl Send for SqliteOwnedBuf {}
unsafe impl Sync for SqliteOwnedBuf {}

impl Drop for SqliteOwnedBuf {
    fn drop(&mut self) {
        unsafe {
            sqlite3_free(self.ptr.as_ptr().cast());
        }
    }
}

impl SqliteOwnedBuf {
    /// Uses `sqlite3_malloc` to allocate a buffer and returns a pointer to it.
    ///
    /// # Safety
    /// The allocated buffer is uninitialized.
    unsafe fn with_capacity(size: usize) -> Option<SqliteOwnedBuf> {
        let ptr = sqlite3_malloc64(u64::try_from(size).unwrap()).cast::<u8>();
        Self::from_raw(ptr, size)
    }

    /// Creates a new mem buffer from a pointer that has been created with sqlite_malloc
    ///
    /// # Safety:
    /// * The pointer must point to a valid allocation created by `sqlite3_malloc()`, or `NULL`.
    unsafe fn from_raw(ptr: *mut u8, size: usize) -> Option<Self> {
        Some(Self {
            ptr: NonNull::new(ptr)?,
            size,
        })
    }

    fn into_raw(self) -> (*mut u8, usize) {
        let raw = (self.ptr.as_ptr(), self.size);
        // this is used in sqlite_deserialize and
        // underlying buffer must not be freed
        std::mem::forget(self);
        raw
    }
}

/// # Errors
/// Returns [`Error::InvalidArgument`] if the slice is empty.
impl TryFrom<&[u8]> for SqliteOwnedBuf {
    type Error = Error;

    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
        unsafe {
            // SAFETY: `buf` is not initialized until `ptr::copy_nonoverlapping` completes.
            let mut buf = Self::with_capacity(bytes.len()).ok_or_else(|| {
                Error::InvalidArgument("SQLite owned buffer cannot be empty".to_string())
            })?;
            ptr::copy_nonoverlapping(bytes.as_ptr(), buf.ptr.as_mut(), buf.size);
            Ok(buf)
        }
    }
}

impl Deref for SqliteOwnedBuf {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.size) }
    }
}

impl DerefMut for SqliteOwnedBuf {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { std::slice::from_raw_parts_mut(self.ptr.as_mut(), self.size) }
    }
}

impl AsRef<[u8]> for SqliteOwnedBuf {
    fn as_ref(&self) -> &[u8] {
        self.deref()
    }
}

impl AsMut<[u8]> for SqliteOwnedBuf {
    fn as_mut(&mut self) -> &mut [u8] {
        self.deref_mut()
    }
}

/// Checked schema name to pass to SQLite.
///
/// # Safety:
/// * Valid UTF-8 (not guaranteed by `CString`)
/// * No internal zero bytes (`\0`) (not guaranteed by `String`)
/// * Terminated with a zero byte (`\0`) (not guaranteed by `String`)
#[derive(Debug)]
pub(crate) struct SchemaName(Box<str>);

impl SchemaName {
    /// Get the schema name as a string without the zero byte terminator.
    pub fn as_str(&self) -> &str {
        &self.0[..self.0.len() - 1]
    }

    /// Get a pointer to the string data, suitable for passing as C's `*const char`.
    ///
    /// # Safety
    /// The string data is guaranteed to be terminated with a zero byte.
    pub fn as_ptr(&self) -> *const c_char {
        self.0.as_ptr() as *const c_char
    }
}

impl<'a> TryFrom<&'a str> for SchemaName {
    type Error = Error;

    fn try_from(name: &'a str) -> Result<Self, Self::Error> {
        // SAFETY: we must ensure that the string does not contain an internal NULL byte
        if let Some(pos) = name.as_bytes().iter().position(|&b| b == 0) {
            return Err(Error::InvalidArgument(format!(
                "schema name {name:?} contains a zero byte at index {pos}"
            )));
        }

        let capacity = name.len().checked_add(1).unwrap();

        let mut s = String::new();
        // `String::with_capacity()` does not guarantee that it will not overallocate,
        // which might mean an unnecessary reallocation to make `capacity == len`
        // in the conversion to `Box<str>`.
        s.reserve_exact(capacity);

        s.push_str(name);
        s.push('\0');

        Ok(SchemaName(s.into()))
    }
}
