// Copyright (c) 2026 Kirky.X
//
// Licensed under the MIT License
// See LICENSE file in the project root for full license information.

//! 属性记录功能
//!
//! 提供在 span 上设置键值对属性的功能。

use opentelemetry::KeyValue;

/// 属性值枚举
///
/// 支持多种类型的属性值。
#[derive(Debug, Clone)]
pub enum AttributeValue {
    /// 字符串值
    String(String),
    /// 64位整数
    I64(i64),
    /// 64位浮点数
    F64(f64),
    /// 布尔值
    Bool(bool),
    /// 数组值（简化处理，转换为字符串）
    Array(Vec<AttributeValue>),
}

impl AttributeValue {
    /// 将属性值转换为 OpenTelemetry KeyValue
    ///
    /// # Arguments
    ///
    /// * `key` - 属性键
    pub fn to_key_value(&self, key: &str) -> KeyValue {
        let key = key.to_string(); // 避免生命周期问题
        match self {
            AttributeValue::String(v) => KeyValue::new(key.clone(), v.clone()),
            AttributeValue::I64(v) => KeyValue::new(key.clone(), *v),
            AttributeValue::F64(v) => KeyValue::new(key.clone(), *v),
            AttributeValue::Bool(v) => KeyValue::new(key.clone(), *v),
            AttributeValue::Array(_) => KeyValue::new(key, "array".to_string()),
        }
    }
}

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

    #[test]
    fn test_string_to_key_value() {
        let value = AttributeValue::String("test".to_string());
        let kv = value.to_key_value("key");
        assert_eq!(kv.key.as_str(), "key");
    }

    #[test]
    fn test_i64_to_key_value() {
        let value = AttributeValue::I64(42);
        let kv = value.to_key_value("count");
        assert_eq!(kv.key.as_str(), "count");
    }

    #[test]
    fn test_f64_to_key_value() {
        let value = AttributeValue::F64(3.14);
        let kv = value.to_key_value("ratio");
        assert_eq!(kv.key.as_str(), "ratio");
    }

    #[test]
    fn test_bool_to_key_value() {
        let value = AttributeValue::Bool(true);
        let kv = value.to_key_value("enabled");
        assert_eq!(kv.key.as_str(), "enabled");
    }

    #[test]
    fn test_array_to_key_value() {
        let value = AttributeValue::Array(vec![AttributeValue::String("a".to_string()), AttributeValue::I64(1)]);
        let kv = value.to_key_value("items");
        assert_eq!(kv.key.as_str(), "items");
    }
}
