use std::sync::OnceLock;

use regex::Regex;

use crate::{error_log, targeting::StringTargetingOperator, utils::regex_utils::make_prohibiting_regex};

pub(super) struct StringValueCondition {
    value: String,
    match_type: StringTargetingOperator,
    value_regex: OnceLock<Regex>,
}

impl StringValueCondition {
    pub fn new(value: String, match_type: String) -> Option<Self> {
        Some(Self {
            value,
            match_type: StringTargetingOperator::from_str(&match_type)?,
            value_regex: OnceLock::new(),
        })
    }

    pub fn check(&self, value: &str) -> bool {
        match self.match_type {
            StringTargetingOperator::Exact => value == self.value,
            StringTargetingOperator::Contains => value.contains(&self.value),
            StringTargetingOperator::Regex => {
                let value_regex = self.value_regex.get_or_init(|| {
                    Regex::new(&self.value).unwrap_or_else(|err| {
                        error_log!("Failed to compile value regex '{}': {err}", self.value);
                        make_prohibiting_regex()
                    })
                });
                value_regex.is_match(value)
            }
        }
    }
}
