use super::value::{DbValue, Op, Operation};

#[derive(Clone, Debug)]
pub struct QueryBuilder {
    pub filters: Vec<Operation>,
    pub updates: Vec<Operation>,
}

impl Default for QueryBuilder {
    fn default() -> Self {
        Self::new()
    }
}

impl QueryBuilder {
    pub fn new() -> Self {
        Self {
            filters: vec![],
            updates: vec![],
        }
    }

    pub fn ne(mut self, field: &'static str, value: impl Into<DbValue>) -> Self {
        self.filters.push(Operation {
            field,
            op: Op::Ne,
            value: value.into(),
        });
        self
    }

    pub fn eq(mut self, field: &'static str, value: impl Into<DbValue>) -> Self {
        self.filters.push(Operation {
            field,
            op: Op::Eq,
            value: value.into(),
        });
        self
    }

    pub fn in_(mut self, field: &'static str, value: impl Into<DbValue>) -> Self {
        self.filters.push(Operation {
            field,
            op: Op::In,
            value: value.into(),
        });
        self
    }

    pub fn gt(mut self, field: &'static str, value: impl Into<DbValue>) -> Self {
        self.filters.push(Operation {
            field,
            op: Op::Gt,
            value: value.into(),
        });
        self
    }

    pub fn set(mut self, field: &'static str, value: impl Into<DbValue>) -> Self {
        self.updates.push(Operation {
            field,
            op: Op::Set,
            value: value.into(),
        });
        self
    }

    pub fn is_null(mut self, field: &'static str) -> Self {
        self.filters.push(Operation {
            field,
            op: Op::Null,
            value: DbValue::Null,
        });
        self
    }
}
