//! Create virtual tables.
//!
//! Follow these steps to create your own virtual table:
//! 1. Write implementation of [`VTab`] and [`VTabCursor`] traits.
//! 2. Create an instance of the [`Module`] structure specialized for [`VTab`]
//! impl. from step 1.
//! 3. Register your [`Module`] structure using [`Connection::create_module`].
//! 4. Run a `CREATE VIRTUAL TABLE` command that specifies the new module in the
//! `USING` clause.
//!
//! (See [SQLite doc](http://sqlite.org/vtab.html))
use std::borrow::Cow::{self, Borrowed, Owned};
use std::marker::PhantomData;
use std::marker::Sync;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
use std::slice;

use crate::context::set_result;
use crate::error::error_from_sqlite_code;
use crate::ffi;
pub use crate::ffi::{sqlite3_vtab, sqlite3_vtab_cursor};
use crate::types::{FromSql, FromSqlError, ToSql, ValueRef};
use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};

// let conn: Connection = ...;
// let mod: Module = ...; // VTab builder
// conn.create_module("module", mod);
//
// conn.execute("CREATE VIRTUAL TABLE foo USING module(...)");
// \-> Module::xcreate
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
// conn = Connection::open(...);
// \-> Module::xconnect
//  |-> let vtab: VTab = ...; // on the heap
//  \-> conn.declare_vtab("CREATE TABLE foo (...)");
//
// conn.close();
// \-> vtab.xdisconnect
// conn.execute("DROP TABLE foo");
// \-> vtab.xDestroy
//
// let stmt = conn.prepare("SELECT ... FROM foo WHERE ...");
// \-> vtab.xbestindex
// stmt.query().next();
// \-> vtab.xopen
//  |-> let cursor: VTabCursor = ...; // on the heap
//  |-> cursor.xfilter or xnext
//  |-> cursor.xeof
//  \-> if not eof { cursor.column or xrowid } else { cursor.xclose }
//

// db: *mut ffi::sqlite3 => VTabConnection
// module: *const ffi::sqlite3_module => Module
// aux: *mut c_void => Module::Aux
// ffi::sqlite3_vtab => VTab
// ffi::sqlite3_vtab_cursor => VTabCursor

/// Virtual table module
///
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
#[repr(transparent)]
pub struct Module<'vtab, T: VTab<'vtab>> {
    base: ffi::sqlite3_module,
    phantom: PhantomData<&'vtab T>,
}

unsafe impl<'vtab, T: VTab<'vtab>> Send for Module<'vtab, T> {}
unsafe impl<'vtab, T: VTab<'vtab>> Sync for Module<'vtab, T> {}

union ModuleZeroHack {
    bytes: [u8; std::mem::size_of::<ffi::sqlite3_module>()],
    module: ffi::sqlite3_module,
}

// Used as a trailing initializer for sqlite3_module -- this way we avoid having
// the build fail if buildtime_bindgen is on. This is safe, as bindgen-generated
// structs are allowed to be zeroed.
const ZERO_MODULE: ffi::sqlite3_module = unsafe {
    ModuleZeroHack {
        bytes: [0_u8; std::mem::size_of::<ffi::sqlite3_module>()],
    }
    .module
};

/// Create a read-only virtual table implementation.
///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[must_use]
pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab, T> {
    // The xConnect and xCreate methods do the same thing, but they must be
    // different so that the virtual table is not an eponymous virtual table.
    #[allow(clippy::needless_update)]
    &Module {
        base: ffi::sqlite3_module {
            // We don't use V3
            iVersion: 2, // We don't use V2 or V3 features in read_only_module types
            xCreate: Some(rust_create::<T>),
            xConnect: Some(rust_connect::<T>),
            xBestIndex: Some(rust_best_index::<T>),
            xDisconnect: Some(rust_disconnect::<T>),
            xDestroy: Some(rust_destroy::<T>),
            xOpen: Some(rust_open::<T>),
            xClose: Some(rust_close::<T::Cursor>),
            xFilter: Some(rust_filter::<T::Cursor>),
            xNext: Some(rust_next::<T::Cursor>),
            xEof: Some(rust_eof::<T::Cursor>),
            xColumn: Some(rust_column::<T::Cursor>),
            xRowid: Some(rust_rowid::<T::Cursor>),
            xUpdate: None,
            xBegin: None,
            xSync: None,
            xCommit: None,
            xRollback: None,
            xFindFunction: None,
            xRename: None,
            xSavepoint: None,
            xRelease: None,
            xRollbackTo: None,
            ..ZERO_MODULE
        },
        phantom: PhantomData::<&'vtab T>,
    }
}

/// Create an eponymous only virtual table implementation.
///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[must_use]
pub fn eponymous_only_module<'vtab, T: VTab<'vtab>>() -> &'static Module<'vtab, T> {
    // A virtual table is eponymous if its xCreate method is the exact same function
    // as the xConnect method For eponymous-only virtual tables, the xCreate
    // method is NULL
    #[allow(clippy::needless_update)]
    &Module {
        base: ffi::sqlite3_module {
            // We don't use V3
            iVersion: 2,
            xCreate: None,
            xConnect: Some(rust_connect::<T>),
            xBestIndex: Some(rust_best_index::<T>),
            xDisconnect: Some(rust_disconnect::<T>),
            xDestroy: None,
            xOpen: Some(rust_open::<T>),
            xClose: Some(rust_close::<T::Cursor>),
            xFilter: Some(rust_filter::<T::Cursor>),
            xNext: Some(rust_next::<T::Cursor>),
            xEof: Some(rust_eof::<T::Cursor>),
            xColumn: Some(rust_column::<T::Cursor>),
            xRowid: Some(rust_rowid::<T::Cursor>),
            xUpdate: None,
            xBegin: None,
            xSync: None,
            xCommit: None,
            xRollback: None,
            xFindFunction: None,
            xRename: None,
            xSavepoint: None,
            xRelease: None,
            xRollbackTo: None,
            ..ZERO_MODULE
        },
        phantom: PhantomData::<&'vtab T>,
    }
}

/// `feature = "vtab"`
pub struct VTabConnection(*mut ffi::sqlite3);

impl VTabConnection {
    // TODO sqlite3_vtab_config (http://sqlite.org/c3ref/vtab_config.html)

    // TODO sqlite3_vtab_on_conflict (http://sqlite.org/c3ref/vtab_on_conflict.html)

    /// Get access to the underlying SQLite database connection handle.
    ///
    /// # Warning
    ///
    /// You should not need to use this function. If you do need to, please
    /// [open an issue on the rusqlite repository](https://github.com/rusqlite/rusqlite/issues) and describe
    /// your use case.
    ///
    /// # Safety
    ///
    /// This function is unsafe because it gives you raw access
    /// to the SQLite connection, and what you do with it could impact the
    /// safety of this `Connection`.
    pub unsafe fn handle(&mut self) -> *mut ffi::sqlite3 {
        self.0
    }
}

/// Virtual table instance trait.
///
/// # Safety
///
/// The first item in a struct implementing `VTab` must be
/// `rusqlite::sqlite3_vtab`, and the struct must be `#[repr(C)]`.
///
/// ```rust,ignore
/// #[repr(C)]
/// struct MyTab {
///    /// Base class. Must be first
///    base: rusqlite::vtab::sqlite3_vtab,
///    /* Virtual table implementations will typically add additional fields */
/// }
/// ```
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
pub unsafe trait VTab<'vtab>: Sized {
    /// Client data passed to [`Connection::create_module`].
    type Aux;
    /// Specific cursor implementation
    type Cursor: VTabCursor;

    /// Establish a new connection to an existing virtual table.
    ///
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
    fn connect(
        db: &mut VTabConnection,
        aux: Option<&Self::Aux>,
        args: &[&[u8]],
    ) -> Result<(String, Self)>;

    /// Determine the best way to access the virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xbestindex_method))
    fn best_index(&self, info: &mut IndexInfo) -> Result<()>;

    /// Create a new cursor used for accessing a virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xopen_method))
    fn open(&'vtab self) -> Result<Self::Cursor>;
}

/// Non-eponymous virtual table instance trait.
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
pub trait CreateVTab<'vtab>: VTab<'vtab> {
    /// Create a new instance of a virtual table in response to a CREATE VIRTUAL
    /// TABLE statement. The `db` parameter is a pointer to the SQLite
    /// database connection that is executing the CREATE VIRTUAL TABLE
    /// statement.
    ///
    /// Call [`connect`](VTab::connect) by default.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcreate_method))
    fn create(
        db: &mut VTabConnection,
        aux: Option<&Self::Aux>,
        args: &[&[u8]],
    ) -> Result<(String, Self)> {
        Self::connect(db, aux, args)
    }

    /// Destroy the underlying table implementation. This method undoes the work
    /// of [`create`](CreateVTab::create).
    ///
    /// Do nothing by default.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xdestroy_method))
    fn destroy(&self) -> Result<()> {
        Ok(())
    }
}

/// Index constraint operator.
/// See [Virtual Table Constraint Operator Codes](https://sqlite.org/c3ref/c_index_constraint_eq.html) for details.
#[derive(Debug, PartialEq)]
#[allow(non_snake_case, non_camel_case_types, missing_docs)]
#[allow(clippy::upper_case_acronyms)]
pub enum IndexConstraintOp {
    SQLITE_INDEX_CONSTRAINT_EQ,
    SQLITE_INDEX_CONSTRAINT_GT,
    SQLITE_INDEX_CONSTRAINT_LE,
    SQLITE_INDEX_CONSTRAINT_LT,
    SQLITE_INDEX_CONSTRAINT_GE,
    SQLITE_INDEX_CONSTRAINT_MATCH,
    SQLITE_INDEX_CONSTRAINT_LIKE,         // 3.10.0
    SQLITE_INDEX_CONSTRAINT_GLOB,         // 3.10.0
    SQLITE_INDEX_CONSTRAINT_REGEXP,       // 3.10.0
    SQLITE_INDEX_CONSTRAINT_NE,           // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNOT,        // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNOTNULL,    // 3.21.0
    SQLITE_INDEX_CONSTRAINT_ISNULL,       // 3.21.0
    SQLITE_INDEX_CONSTRAINT_IS,           // 3.21.0
    SQLITE_INDEX_CONSTRAINT_LIMIT,        // 3.38.0
    SQLITE_INDEX_CONSTRAINT_OFFSET,       // 3.38.0
    SQLITE_INDEX_CONSTRAINT_FUNCTION(u8), // 3.25.0
}

impl From<u8> for IndexConstraintOp {
    fn from(code: u8) -> IndexConstraintOp {
        match code {
            2 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_EQ,
            4 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GT,
            8 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LE,
            16 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LT,
            32 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GE,
            64 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_MATCH,
            65 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LIKE,
            66 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_GLOB,
            67 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_REGEXP,
            68 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_NE,
            69 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNOT,
            70 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNOTNULL,
            71 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_ISNULL,
            72 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_IS,
            73 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_LIMIT,
            74 => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_OFFSET,
            v => IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_FUNCTION(v),
        }
    }
}

/// Pass information into and receive the reply from the
/// [`VTab::best_index`] method.
///
/// (See [SQLite doc](http://sqlite.org/c3ref/index_info.html))
pub struct IndexInfo(*mut ffi::sqlite3_index_info);

impl IndexInfo {
    /// Iterate on index constraint and its associated usage.
    #[inline]
    pub fn constraints_and_usages(&mut self) -> IndexConstraintAndUsageIter<'_> {
        let constraints =
            unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
        let constraint_usages = unsafe {
            slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
        };
        IndexConstraintAndUsageIter {
            iter: constraints.iter().zip(constraint_usages.iter_mut()),
        }
    }

    /// Record WHERE clause constraints.
    #[inline]
    #[must_use]
    pub fn constraints(&self) -> IndexConstraintIter<'_> {
        let constraints =
            unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
        IndexConstraintIter {
            iter: constraints.iter(),
        }
    }

    /// Information about the ORDER BY clause.
    #[inline]
    #[must_use]
    pub fn order_bys(&self) -> OrderByIter<'_> {
        let order_bys =
            unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
        OrderByIter {
            iter: order_bys.iter(),
        }
    }

    /// Number of terms in the ORDER BY clause
    #[inline]
    #[must_use]
    pub fn num_of_order_by(&self) -> usize {
        unsafe { (*self.0).nOrderBy as usize }
    }

    /// Information about what parameters to pass to [`VTabCursor::filter`].
    #[inline]
    pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage<'_> {
        let constraint_usages = unsafe {
            slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
        };
        IndexConstraintUsage(&mut constraint_usages[constraint_idx])
    }

    /// Number used to identify the index
    #[inline]
    pub fn set_idx_num(&mut self, idx_num: c_int) {
        unsafe {
            (*self.0).idxNum = idx_num;
        }
    }

    /// True if output is already ordered
    #[inline]
    pub fn set_order_by_consumed(&mut self, order_by_consumed: bool) {
        unsafe {
            (*self.0).orderByConsumed = if order_by_consumed { 1 } else { 0 };
        }
    }

    /// Estimated cost of using this index
    #[inline]
    pub fn set_estimated_cost(&mut self, estimated_ost: f64) {
        unsafe {
            (*self.0).estimatedCost = estimated_ost;
        }
    }

    /// Estimated number of rows returned.
    #[cfg(feature = "modern_sqlite")] // SQLite >= 3.8.2
    #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
    #[inline]
    pub fn set_estimated_rows(&mut self, estimated_rows: i64) {
        unsafe {
            (*self.0).estimatedRows = estimated_rows;
        }
    }

    // TODO idxFlags
    // TODO colUsed

    // TODO sqlite3_vtab_collation (http://sqlite.org/c3ref/vtab_collation.html)
}

/// Iterate on index constraint and its associated usage.
pub struct IndexConstraintAndUsageIter<'a> {
    iter: std::iter::Zip<
        slice::Iter<'a, ffi::sqlite3_index_constraint>,
        slice::IterMut<'a, ffi::sqlite3_index_constraint_usage>,
    >,
}

impl<'a> Iterator for IndexConstraintAndUsageIter<'a> {
    type Item = (IndexConstraint<'a>, IndexConstraintUsage<'a>);

    #[inline]
    fn next(&mut self) -> Option<(IndexConstraint<'a>, IndexConstraintUsage<'a>)> {
        self.iter
            .next()
            .map(|raw| (IndexConstraint(raw.0), IndexConstraintUsage(raw.1)))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// `feature = "vtab"`
pub struct IndexConstraintIter<'a> {
    iter: slice::Iter<'a, ffi::sqlite3_index_constraint>,
}

impl<'a> Iterator for IndexConstraintIter<'a> {
    type Item = IndexConstraint<'a>;

    #[inline]
    fn next(&mut self) -> Option<IndexConstraint<'a>> {
        self.iter.next().map(IndexConstraint)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// WHERE clause constraint.
pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint);

impl IndexConstraint<'_> {
    /// Column constrained.  -1 for ROWID
    #[inline]
    #[must_use]
    pub fn column(&self) -> c_int {
        self.0.iColumn
    }

    /// Constraint operator
    #[inline]
    #[must_use]
    pub fn operator(&self) -> IndexConstraintOp {
        IndexConstraintOp::from(self.0.op)
    }

    /// True if this constraint is usable
    #[inline]
    #[must_use]
    pub fn is_usable(&self) -> bool {
        self.0.usable != 0
    }
}

/// Information about what parameters to pass to
/// [`VTabCursor::filter`].
pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage);

impl IndexConstraintUsage<'_> {
    /// if `argv_index` > 0, constraint is part of argv to
    /// [`VTabCursor::filter`]
    #[inline]
    pub fn set_argv_index(&mut self, argv_index: c_int) {
        self.0.argvIndex = argv_index;
    }

    /// if `omit`, do not code a test for this constraint
    #[inline]
    pub fn set_omit(&mut self, omit: bool) {
        self.0.omit = if omit { 1 } else { 0 };
    }
}

/// `feature = "vtab"`
pub struct OrderByIter<'a> {
    iter: slice::Iter<'a, ffi::sqlite3_index_info_sqlite3_index_orderby>,
}

impl<'a> Iterator for OrderByIter<'a> {
    type Item = OrderBy<'a>;

    #[inline]
    fn next(&mut self) -> Option<OrderBy<'a>> {
        self.iter.next().map(OrderBy)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

/// A column of the ORDER BY clause.
pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby);

impl OrderBy<'_> {
    /// Column number
    #[inline]
    #[must_use]
    pub fn column(&self) -> c_int {
        self.0.iColumn
    }

    /// True for DESC.  False for ASC.
    #[inline]
    #[must_use]
    pub fn is_order_by_desc(&self) -> bool {
        self.0.desc != 0
    }
}

/// Virtual table cursor trait.
///
/// # Safety
///
/// Implementations must be like:
/// ```rust,ignore
/// #[repr(C)]
/// struct MyTabCursor {
///    /// Base class. Must be first
///    base: rusqlite::vtab::sqlite3_vtab_cursor,
///    /* Virtual table implementations will typically add additional fields */
/// }
/// ```
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab_cursor.html))
pub unsafe trait VTabCursor: Sized {
    /// Begin a search of a virtual table.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xfilter_method))
    fn filter(&mut self, idx_num: c_int, idx_str: Option<&str>, args: &Values<'_>) -> Result<()>;
    /// Advance cursor to the next row of a result set initiated by
    /// [`filter`](VTabCursor::filter). (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method))
    fn next(&mut self) -> Result<()>;
    /// Must return `false` if the cursor currently points to a valid row of
    /// data, or `true` otherwise.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xeof_method))
    fn eof(&self) -> bool;
    /// Find the value for the `i`-th column of the current row.
    /// `i` is zero-based so the first column is numbered 0.
    /// May return its result back to SQLite using one of the specified `ctx`.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcolumn_method))
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()>;
    /// Return the rowid of row that the cursor is currently pointing at.
    /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xrowid_method))
    fn rowid(&self) -> Result<i64>;
}

/// Context is used by [`VTabCursor::column`] to specify the
/// cell value.
pub struct Context(*mut ffi::sqlite3_context);

impl Context {
    /// Set current cell value
    #[inline]
    pub fn set_result<T: ToSql>(&mut self, value: &T) -> Result<()> {
        let t = value.to_sql()?;
        unsafe { set_result(self.0, &t) };
        Ok(())
    }

    // TODO sqlite3_vtab_nochange (http://sqlite.org/c3ref/vtab_nochange.html)
}

/// Wrapper to [`VTabCursor::filter`] arguments, the values
/// requested by [`VTab::best_index`].
pub struct Values<'a> {
    args: &'a [*mut ffi::sqlite3_value],
}

impl Values<'_> {
    /// Returns the number of values.
    #[inline]
    #[must_use]
    pub fn len(&self) -> usize {
        self.args.len()
    }

    /// Returns `true` if there is no value.
    #[inline]
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.args.is_empty()
    }

    /// Returns value at `idx`
    pub fn get<T: FromSql>(&self, idx: usize) -> Result<T> {
        let arg = self.args[idx];
        let value = unsafe { ValueRef::from_value(arg) };
        FromSql::column_result(value).map_err(|err| match err {
            FromSqlError::InvalidType => Error::InvalidFilterParameterType(idx, value.data_type()),
            FromSqlError::Other(err) => {
                Error::FromSqlConversionFailure(idx, value.data_type(), err)
            }
            FromSqlError::InvalidBlobSize { .. } => {
                Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
            }
            FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
        })
    }

    // `sqlite3_value_type` returns `SQLITE_NULL` for pointer.
    // So it seems not possible to enhance `ValueRef::from_value`.
    #[cfg(feature = "array")]
    #[cfg_attr(docsrs, doc(cfg(feature = "array")))]
    fn get_array(&self, idx: usize) -> Option<array::Array> {
        use crate::types::Value;
        let arg = self.args[idx];
        let ptr = unsafe { ffi::sqlite3_value_pointer(arg, array::ARRAY_TYPE) };
        if ptr.is_null() {
            None
        } else {
            Some(unsafe {
                let rc = array::Array::from_raw(ptr as *const Vec<Value>);
                let array = rc.clone();
                array::Array::into_raw(rc); // don't consume it
                array
            })
        }
    }

    /// Turns `Values` into an iterator.
    #[inline]
    #[must_use]
    pub fn iter(&self) -> ValueIter<'_> {
        ValueIter {
            iter: self.args.iter(),
        }
    }
}

impl<'a> IntoIterator for &'a Values<'a> {
    type IntoIter = ValueIter<'a>;
    type Item = ValueRef<'a>;

    #[inline]
    fn into_iter(self) -> ValueIter<'a> {
        self.iter()
    }
}

/// [`Values`] iterator.
pub struct ValueIter<'a> {
    iter: slice::Iter<'a, *mut ffi::sqlite3_value>,
}

impl<'a> Iterator for ValueIter<'a> {
    type Item = ValueRef<'a>;

    #[inline]
    fn next(&mut self) -> Option<ValueRef<'a>> {
        self.iter
            .next()
            .map(|&raw| unsafe { ValueRef::from_value(raw) })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl Connection {
    /// Register a virtual table implementation.
    ///
    /// Step 3 of [Creating New Virtual Table
    /// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
    #[inline]
    pub fn create_module<'vtab, T: VTab<'vtab>>(
        &self,
        module_name: &str,
        module: &'static Module<'vtab, T>,
        aux: Option<T::Aux>,
    ) -> Result<()> {
        self.db.borrow_mut().create_module(module_name, module, aux)
    }
}

impl InnerConnection {
    fn create_module<'vtab, T: VTab<'vtab>>(
        &mut self,
        module_name: &str,
        module: &'static Module<'vtab, T>,
        aux: Option<T::Aux>,
    ) -> Result<()> {
        let c_name = str_to_cstring(module_name)?;
        let r = match aux {
            Some(aux) => {
                let boxed_aux: *mut T::Aux = Box::into_raw(Box::new(aux));
                unsafe {
                    ffi::sqlite3_create_module_v2(
                        self.db(),
                        c_name.as_ptr(),
                        &module.base,
                        boxed_aux.cast::<c_void>(),
                        Some(free_boxed_value::<T::Aux>),
                    )
                }
            }
            None => unsafe {
                ffi::sqlite3_create_module_v2(
                    self.db(),
                    c_name.as_ptr(),
                    &module.base,
                    ptr::null_mut(),
                    None,
                )
            },
        };
        self.decode_result(r)
    }
}

/// Escape double-quote (`"`) character occurrences by
/// doubling them (`""`).
#[must_use]
pub fn escape_double_quote(identifier: &str) -> Cow<'_, str> {
    if identifier.contains('"') {
        // escape quote by doubling them
        Owned(identifier.replace('"', "\"\""))
    } else {
        Borrowed(identifier)
    }
}
/// Dequote string
#[must_use]
pub fn dequote(s: &str) -> &str {
    if s.len() < 2 {
        return s;
    }
    match s.bytes().next() {
        Some(b) if b == b'"' || b == b'\'' => match s.bytes().rev().next() {
            Some(e) if e == b => &s[1..s.len() - 1],
            _ => s,
        },
        _ => s,
    }
}
/// The boolean can be one of:
/// ```text
/// 1 yes true on
/// 0 no false off
/// ```
#[must_use]
pub fn parse_boolean(s: &str) -> Option<bool> {
    if s.eq_ignore_ascii_case("yes")
        || s.eq_ignore_ascii_case("on")
        || s.eq_ignore_ascii_case("true")
        || s.eq("1")
    {
        Some(true)
    } else if s.eq_ignore_ascii_case("no")
        || s.eq_ignore_ascii_case("off")
        || s.eq_ignore_ascii_case("false")
        || s.eq("0")
    {
        Some(false)
    } else {
        None
    }
}

// FIXME copy/paste from function.rs
unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) {
    drop(Box::from_raw(p.cast::<T>()));
}

unsafe extern "C" fn rust_create<'vtab, T>(
    db: *mut ffi::sqlite3,
    aux: *mut c_void,
    argc: c_int,
    argv: *const *const c_char,
    pp_vtab: *mut *mut ffi::sqlite3_vtab,
    err_msg: *mut *mut c_char,
) -> c_int
where
    T: CreateVTab<'vtab>,
{
    use std::ffi::CStr;

    let mut conn = VTabConnection(db);
    let aux = aux.cast::<T::Aux>();
    let args = slice::from_raw_parts(argv, argc as usize);
    let vec = args
        .iter()
        .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
        .collect::<Vec<_>>();
    match T::create(&mut conn, aux.as_ref(), &vec[..]) {
        Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
            Ok(c_sql) => {
                let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
                if rc == ffi::SQLITE_OK {
                    let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
                    *pp_vtab = boxed_vtab.cast::<ffi::sqlite3_vtab>();
                    ffi::SQLITE_OK
                } else {
                    let err = error_from_sqlite_code(rc, None);
                    *err_msg = alloc(&err.to_string());
                    rc
                }
            }
            Err(err) => {
                *err_msg = alloc(&err.to_string());
                ffi::SQLITE_ERROR
            }
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = alloc(&s);
            }
            err.extended_code
        }
        Err(err) => {
            *err_msg = alloc(&err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_connect<'vtab, T>(
    db: *mut ffi::sqlite3,
    aux: *mut c_void,
    argc: c_int,
    argv: *const *const c_char,
    pp_vtab: *mut *mut ffi::sqlite3_vtab,
    err_msg: *mut *mut c_char,
) -> c_int
where
    T: VTab<'vtab>,
{
    use std::ffi::CStr;

    let mut conn = VTabConnection(db);
    let aux = aux.cast::<T::Aux>();
    let args = slice::from_raw_parts(argv, argc as usize);
    let vec = args
        .iter()
        .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
        .collect::<Vec<_>>();
    match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
        Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
            Ok(c_sql) => {
                let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
                if rc == ffi::SQLITE_OK {
                    let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
                    *pp_vtab = boxed_vtab.cast::<ffi::sqlite3_vtab>();
                    ffi::SQLITE_OK
                } else {
                    let err = error_from_sqlite_code(rc, None);
                    *err_msg = alloc(&err.to_string());
                    rc
                }
            }
            Err(err) => {
                *err_msg = alloc(&err.to_string());
                ffi::SQLITE_ERROR
            }
        },
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(s) = s {
                *err_msg = alloc(&s);
            }
            err.extended_code
        }
        Err(err) => {
            *err_msg = alloc(&err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_best_index<'vtab, T>(
    vtab: *mut ffi::sqlite3_vtab,
    info: *mut ffi::sqlite3_index_info,
) -> c_int
where
    T: VTab<'vtab>,
{
    let vt = vtab.cast::<T>();
    let mut idx_info = IndexInfo(info);
    match (*vt).best_index(&mut idx_info) {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_disconnect<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where
    T: VTab<'vtab>,
{
    if vtab.is_null() {
        return ffi::SQLITE_OK;
    }
    let vtab = vtab.cast::<T>();
    drop(Box::from_raw(vtab));
    ffi::SQLITE_OK
}

unsafe extern "C" fn rust_destroy<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where
    T: CreateVTab<'vtab>,
{
    if vtab.is_null() {
        return ffi::SQLITE_OK;
    }
    let vt = vtab.cast::<T>();
    match (*vt).destroy() {
        Ok(_) => {
            drop(Box::from_raw(vt));
            ffi::SQLITE_OK
        }
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_open<'vtab, T: 'vtab>(
    vtab: *mut ffi::sqlite3_vtab,
    pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
) -> c_int
where
    T: VTab<'vtab>,
{
    let vt = vtab.cast::<T>();
    match (*vt).open() {
        Ok(cursor) => {
            let boxed_cursor: *mut T::Cursor = Box::into_raw(Box::new(cursor));
            *pp_cursor = boxed_cursor.cast::<ffi::sqlite3_vtab_cursor>();
            ffi::SQLITE_OK
        }
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg(vtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg(vtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

unsafe extern "C" fn rust_close<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    drop(Box::from_raw(cr));
    ffi::SQLITE_OK
}

unsafe extern "C" fn rust_filter<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    idx_num: c_int,
    idx_str: *const c_char,
    argc: c_int,
    argv: *mut *mut ffi::sqlite3_value,
) -> c_int
where
    C: VTabCursor,
{
    use std::ffi::CStr;
    use std::str;
    let idx_name = if idx_str.is_null() {
        None
    } else {
        let c_slice = CStr::from_ptr(idx_str).to_bytes();
        Some(str::from_utf8_unchecked(c_slice))
    };
    let args = slice::from_raw_parts_mut(argv, argc as usize);
    let values = Values { args };
    let cr = cursor as *mut C;
    cursor_error(cursor, (*cr).filter(idx_num, idx_name, &values))
}

unsafe extern "C" fn rust_next<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor as *mut C;
    cursor_error(cursor, (*cr).next())
}

unsafe extern "C" fn rust_eof<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    (*cr).eof() as c_int
}

unsafe extern "C" fn rust_column<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    ctx: *mut ffi::sqlite3_context,
    i: c_int,
) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    let mut ctxt = Context(ctx);
    result_error(ctx, (*cr).column(&mut ctxt, i))
}

unsafe extern "C" fn rust_rowid<C>(
    cursor: *mut ffi::sqlite3_vtab_cursor,
    p_rowid: *mut ffi::sqlite3_int64,
) -> c_int
where
    C: VTabCursor,
{
    let cr = cursor.cast::<C>();
    match (*cr).rowid() {
        Ok(rowid) => {
            *p_rowid = rowid;
            ffi::SQLITE_OK
        }
        err => cursor_error(cursor, err),
    }
}

/// Virtual table cursors can set an error message by assigning a string to
/// `zErrMsg`.
#[cold]
unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int {
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            if let Some(err_msg) = s {
                set_err_msg((*cursor).pVtab, &err_msg);
            }
            err.extended_code
        }
        Err(err) => {
            set_err_msg((*cursor).pVtab, &err.to_string());
            ffi::SQLITE_ERROR
        }
    }
}

/// Virtual tables methods can set an error message by assigning a string to
/// `zErrMsg`.
#[cold]
unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
    if !(*vtab).zErrMsg.is_null() {
        ffi::sqlite3_free((*vtab).zErrMsg.cast::<c_void>());
    }
    (*vtab).zErrMsg = alloc(err_msg);
}

/// To raise an error, the `column` method should use this method to set the
/// error message and return the error code.
#[cold]
unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> c_int {
    match result {
        Ok(_) => ffi::SQLITE_OK,
        Err(Error::SqliteFailure(err, s)) => {
            match err.extended_code {
                ffi::SQLITE_TOOBIG => {
                    ffi::sqlite3_result_error_toobig(ctx);
                }
                ffi::SQLITE_NOMEM => {
                    ffi::sqlite3_result_error_nomem(ctx);
                }
                code => {
                    ffi::sqlite3_result_error_code(ctx, code);
                    if let Some(Ok(cstr)) = s.map(|s| str_to_cstring(&s)) {
                        ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
                    }
                }
            };
            err.extended_code
        }
        Err(err) => {
            ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_ERROR);
            if let Ok(cstr) = str_to_cstring(&err.to_string()) {
                ffi::sqlite3_result_error(ctx, cstr.as_ptr(), -1);
            }
            ffi::SQLITE_ERROR
        }
    }
}

// Space to hold this string must be obtained
// from an SQLite memory allocation function
fn alloc(s: &str) -> *mut c_char {
    crate::util::SqliteMallocString::from_str(s).into_raw()
}

#[cfg(feature = "array")]
#[cfg_attr(docsrs, doc(cfg(feature = "array")))]
pub mod array;
#[cfg(feature = "csvtab")]
#[cfg_attr(docsrs, doc(cfg(feature = "csvtab")))]
pub mod csvtab;
#[cfg(feature = "series")]
#[cfg_attr(docsrs, doc(cfg(feature = "series")))]
pub mod series; // SQLite >= 3.9.0

#[cfg(test)]
mod test {
    #[test]
    fn test_dequote() {
        assert_eq!("", super::dequote(""));
        assert_eq!("'", super::dequote("'"));
        assert_eq!("\"", super::dequote("\""));
        assert_eq!("'\"", super::dequote("'\""));
        assert_eq!("", super::dequote("''"));
        assert_eq!("", super::dequote("\"\""));
        assert_eq!("x", super::dequote("'x'"));
        assert_eq!("x", super::dequote("\"x\""));
        assert_eq!("x", super::dequote("x"));
    }
    #[test]
    fn test_parse_boolean() {
        assert_eq!(None, super::parse_boolean(""));
        assert_eq!(Some(true), super::parse_boolean("1"));
        assert_eq!(Some(true), super::parse_boolean("yes"));
        assert_eq!(Some(true), super::parse_boolean("on"));
        assert_eq!(Some(true), super::parse_boolean("true"));
        assert_eq!(Some(false), super::parse_boolean("0"));
        assert_eq!(Some(false), super::parse_boolean("no"));
        assert_eq!(Some(false), super::parse_boolean("off"));
        assert_eq!(Some(false), super::parse_boolean("false"));
    }
}
