//! Content annotations
//!
//! Annotations provide metadata about content (audience, priority, timestamps, etc.)
//! Based on MCP 2025-11-25 spec and Go mcphost implementation

use serde::{Deserialize, Serialize};

/// Content annotations
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Annotations {
    /// Target audience for this content
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audience: Option<Vec<String>>,

    /// Priority level (0.0 to 1.0, higher = more important)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub priority: Option<f64>,

    /// Timestamp when content was last modified (ISO 8601)
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last_modified: Option<String>,

    /// Language code (e.g., "en", "es", "fr")
    #[serde(skip_serializing_if = "Option::is_none")]
    pub language: Option<String>,
}

impl Annotations {
    /// Create new empty annotations
    pub fn new() -> Self {
        Self::default()
    }

    /// Set audience
    pub fn with_audience(mut self, audience: Vec<String>) -> Self {
        self.audience = Some(audience);
        self
    }

    /// Add single audience member
    pub fn add_audience(mut self, audience: impl Into<String>) -> Self {
        self.audience
            .get_or_insert_with(Vec::new)
            .push(audience.into());
        self
    }

    /// Set priority (clamped to 0.0-1.0)
    pub fn with_priority(mut self, priority: f64) -> Self {
        self.priority = Some(priority.clamp(0.0, 1.0));
        self
    }

    /// Set last modified timestamp
    pub fn with_last_modified(mut self, timestamp: impl Into<String>) -> Self {
        self.last_modified = Some(timestamp.into());
        self
    }

    /// Set language
    pub fn with_language(mut self, language: impl Into<String>) -> Self {
        self.language = Some(language.into());
        self
    }
}

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

    #[test]
    fn test_annotations_builder() {
        let ann = Annotations::new()
            .with_priority(0.8)
            .add_audience("user")
            .add_audience("admin")
            .with_language("en");

        assert_eq!(ann.priority, Some(0.8));
        assert_eq!(
            ann.audience,
            Some(vec!["user".to_string(), "admin".to_string()])
        );
        assert_eq!(ann.language, Some("en".to_string()));
    }

    #[test]
    fn test_priority_clamping() {
        let ann = Annotations::new().with_priority(1.5);
        assert_eq!(ann.priority, Some(1.0));

        let ann = Annotations::new().with_priority(-0.5);
        assert_eq!(ann.priority, Some(0.0));
    }

    #[test]
    fn test_serialization() {
        let ann = Annotations::new().with_priority(0.9).with_language("en");

        let json = serde_json::to_value(&ann).unwrap();
        assert_eq!(json["priority"], 0.9);
        assert_eq!(json["language"], "en");
        assert!(json.get("audience").is_none()); // Not serialized if None
    }
}
