// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Helper functions and macros for working with events.

use crate::event::{AttributeMap, AttributeValue};

/// Creates a string attribute value.
///
/// # Arguments
///
/// * `value` - A string slice that holds the value to be converted.
///
/// # Returns
///
/// * `AttributeValue::String` - An `AttributeValue` enum variant containing the string value.
pub fn string_attr(value: &str) -> AttributeValue {
    AttributeValue::String(value.to_string())
}

/// Creates an integer attribute value.
///
/// # Arguments
///
/// * `value` - An integer value to be converted.
///
/// # Returns
///
/// * `AttributeValue::Integer` - An `AttributeValue` enum variant containing the integer value.
pub fn int_attr(value: i64) -> AttributeValue {
    AttributeValue::Integer(value)
}

/// Creates a float attribute value.
///
/// # Arguments
///
/// * `value` - A float value to be converted.
///
/// # Returns
///
/// * `AttributeValue::Float` - An `AttributeValue` enum variant containing the float value.
pub fn float_attr(value: f64) -> AttributeValue {
    AttributeValue::Float(value)
}

/// Creates a boolean attribute value.
///
/// # Arguments
///
/// * `value` - A boolean value to be converted.
///
/// # Returns
///
/// * `AttributeValue::Boolean` - An `AttributeValue` enum variant containing the boolean value.
pub fn bool_attr(value: bool) -> AttributeValue {
    AttributeValue::Boolean(value)
}

/// Creates a list attribute value.
///
/// # Arguments
///
/// * `values` - A vector of `AttributeValue` to be converted.
///
/// # Returns
///
/// * `AttributeValue::List` - An `AttributeValue` enum variant containing the list of attribute values.
pub fn list_attr(values: Vec<AttributeValue>) -> AttributeValue {
    AttributeValue::List(values)
}

/// Creates a map attribute value.
///
/// # Arguments
///
/// * `map` - Any map-like structure that can be converted to an `AttributeMap`
///   (such as `HashMap`, `BTreeMap`, or `AttributeMap` itself).
///
/// # Returns
///
/// * `AttributeValue::Map` - An `AttributeValue` enum variant containing the map of attribute values.
pub fn map_attr<M>(map: M) -> AttributeValue
where
    M: IntoIterator<Item = (String, AttributeValue)>,
{
    AttributeValue::Map(AttributeMap::from_iter(map))
}

#[macro_export]
macro_rules! attr_map {
    ( $( $key:expr => $value:expr ),* $(,)? ) => {
        {
            let mut map = AttributeMap::new();
            $(
                map.insert($key.to_string(), $value);
            )*
            map
        }
    };
}

#[macro_export]
macro_rules! list_from_ints {
    ( $( $value:expr ),* $(,)? ) => {
        AttributeValue::List(vec![ $( AttributeValue::Integer($value as i64) ),* ])
    };
}

#[macro_export]
macro_rules! list_from_strs {
    ( $( $value:expr ),* $(,)? ) => {
        AttributeValue::List(vec![ $( AttributeValue::String($value.to_string()) ),* ])
    };
}

#[macro_export]
macro_rules! list_from_floats {
    ( $( $value:expr ),* $(,)? ) => {
        AttributeValue::List(vec![ $( AttributeValue::Float($value as f64) ),* ])
    };
}

#[macro_export]
macro_rules! list_from_bools {
    ( $( $value:expr ),* $(,)? ) => {
        AttributeValue::List(vec![ $( AttributeValue::Boolean($value) ),* ])
    };
}

#[macro_export]
macro_rules! map_from_attr_values {
    ( $( $key:expr => $value:expr ),* $(,)? ) => {
        AttributeValue::Map(attr_map!( $( $key => $value ),* ))
    };
}

#[macro_export]
macro_rules! list_from_attr_values {
    ( $( $value:expr ),* $(,)? ) => {
        AttributeValue::List(vec![ $( $value ),* ])
    };
}
