use crate::{
    datafile::datafile::DataFile,
    targeting::{
        conditions::{string_value_condition::StringValueCondition, TargetingCondition},
        models::VisitorCodeCPModel,
        TargetingData,
    },
};

pub(crate) struct VisitorCodeCondition {
    string_condition: StringValueCondition,
}

impl VisitorCodeCondition {
    pub fn from_json(model: VisitorCodeCPModel) -> Option<Self> {
        let string_condition = StringValueCondition::new(model.visitor_code, model.match_type)?;
        return Some(Self { string_condition });
    }
}

impl TargetingCondition for VisitorCodeCondition {
    fn check(&self, data: &TargetingData<impl DataFile>) -> Option<bool> {
        return Some(self.string_condition.check(data.visitor_code));
    }
}

#[cfg(test)]
mod tests {
    use crate::{
        datafile::datafile_test_utils::MockDataFile, storage::visitor::Visitor, targeting::TargetingDataBuilder,
        utils::test_utils::assert_targeting,
    };

    use rstest::rstest;

    #[rstest]
    #[case("Hello Dear Friend", true)]
    #[case("Hello Friend", false)]
    #[case("", false)]
    fn test_check(#[case] visitor_code: &str, #[case] expected: bool) {
        let datafile = MockDataFile::default();
        let visitor = Visitor::new();
        assert_targeting(
            "resources/conditions/mock_segment_visitor.json",
            &TargetingDataBuilder::new().visitor_code(visitor_code).build(&datafile, &visitor.rdata()),
            expected,
        );
    }
}
