//! Eval implementations for regex functions

use regex::Regex;

use hamelin_lib::func::defs::{RegexpReplace2, RegexpReplace3, RegexpSplit};

use crate::null_propagate;
use crate::registry::EvalRegistry;
use crate::value::Value;

/// Register all regex function eval implementations.
pub fn register(registry: &mut EvalRegistry) {
    // regexp_replace(string, pattern) - removes all matches
    registry.register_eval::<RegexpReplace2>(|mut params| {
        let string = null_propagate!(params.take()?).require_string()?;
        let pattern = null_propagate!(params.take()?).require_string()?;
        let regex =
            Regex::new(&pattern).map_err(|e| anyhow::anyhow!("Invalid regex pattern: {}", e))?;
        Ok(Value::String(regex.replace_all(&string, "").to_string()))
    });

    // regexp_replace(string, pattern, replacement) - replaces all matches
    registry.register_eval::<RegexpReplace3>(|mut params| {
        let string = null_propagate!(params.take()?).require_string()?;
        let pattern = null_propagate!(params.take()?).require_string()?;
        let replacement = null_propagate!(params.take()?).require_string()?;
        let regex =
            Regex::new(&pattern).map_err(|e| anyhow::anyhow!("Invalid regex pattern: {}", e))?;
        Ok(Value::String(
            regex.replace_all(&string, replacement.as_str()).to_string(),
        ))
    });

    // regexp_split(string, pattern) - splits string by regex pattern
    registry.register_eval::<RegexpSplit>(|mut params| {
        let string = null_propagate!(params.take()?).require_string()?;
        let pattern = null_propagate!(params.take()?).require_string()?;
        let regex =
            Regex::new(&pattern).map_err(|e| anyhow::anyhow!("Invalid regex pattern: {}", e))?;
        let parts: Vec<Value> = regex
            .split(&string)
            .map(|s| Value::String(s.to_string()))
            .collect();
        Ok(Value::Array(parts))
    });

    // No reverse eval for regex functions - they're not invertible
}
