mod column_list;
mod insert_from_select;

pub(crate) use self::column_list::ColumnList;
pub(crate) use self::insert_from_select::InsertFromSelect;

use std::any::*;
use std::marker::PhantomData;

use super::returning_clause::*;
use crate::backend::Backend;
use crate::expression::operators::Eq;
use crate::expression::{Expression, NonAggregate, SelectableExpression};
use crate::insertable::*;
#[cfg(feature = "mysql")]
use crate::mysql::Mysql;
use crate::query_builder::*;
#[cfg(feature = "sqlite")]
use crate::query_dsl::methods::ExecuteDsl;
use crate::query_dsl::RunQueryDsl;
use crate::query_source::{Column, Table};
use crate::result::QueryResult;
#[cfg(feature = "sqlite")]
use crate::sqlite::{Sqlite, SqliteConnection};

/// The structure returned by [`insert_into`].
///
/// The provided methods [`values`] and [`default_values`] will insert
/// data into the targeted table.
///
/// [`insert_into`]: ../fn.insert_into.html
/// [`values`]: #method.values
/// [`default_values`]: #method.default_values
#[derive(Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
pub struct IncompleteInsertStatement<T, Op> {
    target: T,
    operator: Op,
}

impl<T, Op> IncompleteInsertStatement<T, Op> {
    pub(crate) fn new(target: T, operator: Op) -> Self {
        IncompleteInsertStatement { target, operator }
    }

    /// Inserts `DEFAULT VALUES` into the targeted table.
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users (name) {
    /// #         name -> Text,
    /// #         hair_color -> Text,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     run_test();
    /// # }
    /// #
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::insert_into;
    /// #     use self::users::dsl::*;
    /// #     let connection = connection_no_data();
    /// connection.execute("CREATE TABLE users (
    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
    /// )")?;
    ///
    /// insert_into(users)
    ///     .default_values()
    ///     .execute(&connection)
    ///     .unwrap();
    /// let inserted_user = users.first(&connection)?;
    /// let expected_data = (String::from("Sean"), String::from("Green"));
    ///
    /// assert_eq!(expected_data, inserted_user);
    /// #     Ok(())
    /// # }
    /// ```
    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
        static STATIC_DEFAULT_VALUES: &DefaultValues = &DefaultValues;
        self.values(STATIC_DEFAULT_VALUES)
    }

    /// Inserts the given values into the table passed to `insert_into`.
    ///
    /// See the documentation of [`insert_into`] for
    /// usage examples.
    ///
    /// This method can sometimes produce extremely opaque error messages due to
    /// limitations of the Rust language. If you receive an error about
    /// "overflow evaluating requirement" as a result of calling this method,
    /// you may need an `&` in front of the argument to this method.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
    where
        U: Insertable<T>,
    {
        InsertStatement::new(
            self.target,
            records.values(),
            self.operator,
            NoReturningClause,
        )
    }
}

#[derive(Debug, Copy, Clone)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// A fully constructed insert statement.
///
/// The parameters of this struct represent:
///
/// - `T`: The table we are inserting into
/// - `U`: The data being inserted
/// - `Op`: The operation being performed. The specific types used to represent
///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
///   You can safely rely on the default type representing `INSERT`
/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
///   represent this are private. You can safely rely on the default type
///   representing a query without a `RETURNING` clause.
pub struct InsertStatement<T, U, Op = Insert, Ret = NoReturningClause> {
    operator: Op,
    target: T,
    records: U,
    returning: Ret,
}

impl<T, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
    fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
        InsertStatement {
            operator: operator,
            target: target,
            records: records,
            returning: returning,
        }
    }

    #[cfg(feature = "postgres")]
    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
    where
        F: FnOnce(U) -> V,
    {
        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
    }
}

impl<T, U, C, Op, Ret> InsertStatement<T, InsertFromSelect<U, C>, Op, Ret> {
    /// Set the column list when inserting from a select statement
    ///
    /// See the documentation for [`insert_into`] for usage examples.
    ///
    /// [`insert_into`]: ../fn.insert_into.html
    pub fn into_columns<C2>(
        self,
        columns: C2,
    ) -> InsertStatement<T, InsertFromSelect<U, C2>, Op, Ret>
    where
        C2: ColumnList<Table = T> + Expression<SqlType = U::SqlType>,
        U: Query,
    {
        InsertStatement::new(
            self.target,
            self.records.with_columns(columns),
            self.operator,
            self.returning,
        )
    }
}

impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
where
    DB: Backend,
    T: Table,
    T::FromClause: QueryFragment<DB>,
    U: QueryFragment<DB> + CanInsertInSingleQuery<DB>,
    Op: QueryFragment<DB>,
    Ret: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();

        if self.records.rows_to_insert() == Some(0) {
            out.push_sql("SELECT 1 FROM ");
            self.target.from_clause().walk_ast(out.reborrow())?;
            out.push_sql(" WHERE 1=0");
            return Ok(());
        }

        self.operator.walk_ast(out.reborrow())?;
        out.push_sql(" INTO ");
        self.target.from_clause().walk_ast(out.reborrow())?;
        out.push_sql(" ");
        self.records.walk_ast(out.reborrow())?;
        self.returning.walk_ast(out.reborrow())?;
        Ok(())
    }
}

#[cfg(feature = "sqlite")]
impl<'a, T, U, Op> ExecuteDsl<SqliteConnection> for InsertStatement<T, BatchInsert<'a, U, T>, Op>
where
    &'a U: Insertable<T>,
    InsertStatement<T, <&'a U as Insertable<T>>::Values, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use crate::connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for record in query.records.records {
                result += InsertStatement::new(
                    query.target,
                    record.values(),
                    query.operator,
                    query.returning,
                )
                .execute(conn)?;
            }
            Ok(result)
        })
    }
}

#[cfg(feature = "sqlite")]
impl<T, U, Op> ExecuteDsl<SqliteConnection>
    for InsertStatement<T, OwnedBatchInsert<ValuesClause<U, T>, T>, Op>
where
    InsertStatement<T, ValuesClause<U, T>, Op>: QueryFragment<Sqlite>,
    T: Copy,
    Op: Copy,
{
    fn execute(query: Self, conn: &SqliteConnection) -> QueryResult<usize> {
        use crate::connection::Connection;
        conn.transaction(|| {
            let mut result = 0;
            for value in query.records.values {
                result +=
                    InsertStatement::new(query.target, value, query.operator, query.returning)
                        .execute(conn)?;
            }
            Ok(result)
        })
    }
}

impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
where
    T: Table,
    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
{
    type SqlType = <Self::Query as Query>::SqlType;
    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;

    fn as_query(self) -> Self::Query {
        self.returning(T::all_columns())
    }
}

impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
where
    Ret: Expression + SelectableExpression<T> + NonAggregate,
{
    type SqlType = Ret::SqlType;
}

impl<T, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}

impl<T, U, Op> InsertStatement<T, U, Op> {
    /// Specify what expression is returned after execution of the `insert`.
    /// # Examples
    ///
    /// ### Inserting records:
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # #[cfg(feature = "postgres")]
    /// # fn main() {
    /// #     use schema::users::dsl::*;
    /// #     let connection = establish_connection();
    /// let inserted_names = diesel::insert_into(users)
    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
    ///     .returning(name)
    ///     .get_results(&connection);
    /// assert_eq!(Ok(vec!["Timmy".to_string(), "Jimmy".to_string()]), inserted_names);
    /// # }
    /// # #[cfg(not(feature = "postgres"))]
    /// # fn main() {}
    /// ```
    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
    where
        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
    {
        InsertStatement::new(
            self.target,
            self.records,
            self.operator,
            ReturningClause(returns),
        )
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct Insert;

impl<DB: Backend> QueryFragment<DB> for Insert {
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("INSERT");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone, QueryId)]
#[doc(hidden)]
pub struct InsertOrIgnore;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("INSERT OR IGNORE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for InsertOrIgnore {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("INSERT IGNORE");
        Ok(())
    }
}

#[derive(Debug, Copy, Clone)]
#[doc(hidden)]
pub struct Replace;

#[cfg(feature = "sqlite")]
impl QueryFragment<Sqlite> for Replace {
    fn walk_ast(&self, mut out: AstPass<Sqlite>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

#[cfg(feature = "mysql")]
impl QueryFragment<Mysql> for Replace {
    fn walk_ast(&self, mut out: AstPass<Mysql>) -> QueryResult<()> {
        out.push_sql("REPLACE");
        Ok(())
    }
}

/// Marker trait to indicate that no additional operations have been added
/// to a record for insert.
///
/// This is used to prevent things like
/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
/// from compiling.
pub trait UndecoratedInsertRecord<Table> {}

impl<'a, T, Tab> UndecoratedInsertRecord<Tab> for &'a T where
    T: ?Sized + UndecoratedInsertRecord<Tab>
{
}

impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U> where T: Column {}

impl<T, Table> UndecoratedInsertRecord<Table> for [T] where T: UndecoratedInsertRecord<Table> {}

impl<'a, T, Table> UndecoratedInsertRecord<Table> for BatchInsert<'a, T, Table> where
    T: UndecoratedInsertRecord<Table>
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for OwnedBatchInsert<T, Table> where
    T: UndecoratedInsertRecord<Table>
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T> where [T]: UndecoratedInsertRecord<Table> {}

impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs> where Lhs: Column {}

impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>> where
    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>
{
}

impl<T, Table> UndecoratedInsertRecord<Table> for ValuesClause<T, Table> where
    T: UndecoratedInsertRecord<Table>
{
}

#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct DefaultValues;

impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
    fn rows_to_insert(&self) -> Option<usize> {
        Some(1)
    }
}

impl<'a, Tab> Insertable<Tab> for &'a DefaultValues {
    type Values = DefaultValues;

    fn values(self) -> Self::Values {
        *self
    }
}

impl<DB> QueryFragment<DB> for DefaultValues
where
    DB: Backend + Any,
{
    #[cfg(feature = "mysql")]
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        // This can be less hacky once stabilization lands
        if TypeId::of::<DB>() == TypeId::of::<crate::mysql::Mysql>() {
            out.push_sql("() VALUES ()");
        } else {
            out.push_sql("DEFAULT VALUES");
        }
        Ok(())
    }

    #[cfg(not(feature = "mysql"))]
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("DEFAULT VALUES");
        Ok(())
    }
}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ValuesClause<T, Tab> {
    pub values: T,
    _marker: PhantomData<Tab>,
}

impl<T: Default, Tab> Default for ValuesClause<T, Tab> {
    fn default() -> Self {
        Self::new(T::default())
    }
}

impl<T, Tab> ValuesClause<T, Tab> {
    pub(crate) fn new(values: T) -> Self {
        Self {
            values,
            _marker: PhantomData,
        }
    }
}

impl<T, Tab, DB> CanInsertInSingleQuery<DB> for ValuesClause<T, Tab>
where
    DB: Backend,
    T: CanInsertInSingleQuery<DB>,
{
    fn rows_to_insert(&self) -> Option<usize> {
        self.values.rows_to_insert()
    }
}

impl<T, Tab, DB> QueryFragment<DB> for ValuesClause<T, Tab>
where
    DB: Backend,
    Tab: Table,
    T: InsertValues<Tab, DB>,
    DefaultValues: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        if self.values.is_noop()? {
            DefaultValues.walk_ast(out)?;
        } else {
            out.push_sql("(");
            self.values.column_names(out.reborrow())?;
            out.push_sql(") VALUES (");
            self.values.walk_ast(out.reborrow())?;
            out.push_sql(")");
        }
        Ok(())
    }
}
