use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub(crate) fn serialize_thing_keys<S: Serializer>(
    keys: &[String],
    s: S,
) -> Result<S::Ok, S::Error> {
    s.serialize_str(&keys.join(", "))
}

pub(crate) fn deserialize_thing_keys<'de, D: Deserializer<'de>>(
    d: D,
) -> Result<Vec<String>, D::Error> {
    let s = String::deserialize(d)?;
    Ok(s.split(',')
        .map(|k| k.trim().to_owned())
        .filter(|k| !k.is_empty())
        .collect())
}

/// Selects which measurement fields to include in the response.
#[derive(Debug, Clone, PartialEq, Default)]
pub enum RequiredValues {
    /// Request all available fields (serialized as `"*"`).
    #[default]
    All,
    /// Request a specific subset of named fields.
    Fields(Vec<String>),
}

impl Serialize for RequiredValues {
    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
        match self {
            RequiredValues::All => s.serialize_str("*"),
            RequiredValues::Fields(fields) => s.serialize_str(&fields.join(", ")),
        }
    }
}

impl<'de> Deserialize<'de> for RequiredValues {
    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
        let s = String::deserialize(d)?;
        if s.trim() == "*" {
            Ok(RequiredValues::All)
        } else {
            Ok(RequiredValues::Fields(
                s.split(',')
                    .map(|f| f.trim().to_owned())
                    .filter(|f| !f.is_empty())
                    .collect(),
            ))
        }
    }
}
