use std::fmt::{self, Display, Formatter};

use crate::sql::expression::literal::StringLiteral;
use crate::sql::expression::SQLExpression;
use crate::write_utils::Indent;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RegexpCountFunction {
    pub value: Box<SQLExpression>,
    pub regex: StringLiteral,
}

impl RegexpCountFunction {
    pub fn new(value: SQLExpression, regex: StringLiteral) -> Self {
        Self {
            value: Box::new(value),
            regex,
        }
    }

    pub fn fmt_indented(&self, f: &mut Formatter<'_>, _indentation: Indent) -> fmt::Result {
        write!(f, "regexp_count({}, {})", self.value, self.regex)
    }
}

impl Display for RegexpCountFunction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.fmt_indented(f, Indent::default())
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RegexpExtractFunction {
    pub value: Box<SQLExpression>,
    pub regex: StringLiteral,
    pub index: usize,
}

impl RegexpExtractFunction {
    pub fn new(value: SQLExpression, regex: StringLiteral, index: usize) -> Self {
        Self {
            value: Box::new(value),
            regex,
            index,
        }
    }

    pub fn fmt_indented(&self, f: &mut Formatter<'_>, _indentation: Indent) -> fmt::Result {
        write!(
            f,
            "regexp_extract({}, {}, {})",
            self.value, self.regex, self.index
        )
    }
}

impl Display for RegexpExtractFunction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.fmt_indented(f, Indent::default())
    }
}
