//! Parsing and validation for `room_id` filter values in gateway conditions.

use serde_json::{Number, Value};

/// Parses `eq_value` for a `room_id` condition (integer, or non-empty numeric string; rejects `*`).
pub fn parse_room_id_value(value: &Value) -> Result<i64, String> {
    match value {
        Value::Number(num) => num
            .as_i64()
            .ok_or_else(|| "room_id must be an integer".to_string()),
        Value::String(text) => {
            let trimmed = text.trim();
            if trimmed == "*" {
                return Err("room_id wildcard '*' is not allowed".to_string());
            }
            if trimmed.is_empty() {
                return Err("room_id must not be empty".to_string());
            }
            trimmed
                .parse::<i64>()
                .map_err(|_| "room_id must be numeric".to_string())
        }
        _ => Err("room_id must be numeric".to_string()),
    }
}

/// Coerces `eq_value` to a JSON number when the column is `room_id` / `roomId`.
#[allow(dead_code)]
pub fn coerce_room_id_eq_value(eq_value_raw: &Value) -> Result<Value, String> {
    parse_room_id_value(eq_value_raw).map(|id| Value::Number(Number::from(id)))
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn parses_integer() {
        assert_eq!(parse_room_id_value(&json!(42)).unwrap(), 42);
    }

    #[test]
    fn rejects_wildcard() {
        assert!(parse_room_id_value(&json!("*")).is_err());
    }
}
