//! A2A Protocol message types
//!
//! Implements Google A2A spec message types for agent-to-agent communication.

use serde::{Deserialize, Serialize};

/// A2A message types per Google A2A spec
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum A2aMessageType {
    /// Request data processing
    ProcessData,
    /// Request information
    RequestInfo,
    /// Request action execution
    ExecuteAction,
    /// Coordinate multi-agent workflow
    Coordinate,
    /// Send notification (fire-and-forget)
    Notify,
    /// Query agent capabilities
    Query,
}

impl A2aMessageType {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::ProcessData => "PROCESS_DATA",
            Self::RequestInfo => "REQUEST_INFO",
            Self::ExecuteAction => "EXECUTE_ACTION",
            Self::Coordinate => "COORDINATE",
            Self::Notify => "NOTIFY",
            Self::Query => "QUERY",
        }
    }
}

impl std::fmt::Display for A2aMessageType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

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

    #[test]
    fn test_message_type_serialization() {
        let msg_type = A2aMessageType::ProcessData;
        let json = serde_json::to_string(&msg_type).unwrap();
        assert_eq!(json, "\"PROCESS_DATA\"");
    }

    #[test]
    fn test_message_type_deserialization() {
        let json = "\"EXECUTE_ACTION\"";
        let msg_type: A2aMessageType = serde_json::from_str(json).unwrap();
        assert_eq!(msg_type, A2aMessageType::ExecuteAction);
    }

    #[test]
    fn test_all_message_types() {
        let types = [
            A2aMessageType::ProcessData,
            A2aMessageType::RequestInfo,
            A2aMessageType::ExecuteAction,
            A2aMessageType::Coordinate,
            A2aMessageType::Notify,
            A2aMessageType::Query,
        ];
        for t in types {
            let json = serde_json::to_string(&t).unwrap();
            let parsed: A2aMessageType = serde_json::from_str(&json).unwrap();
            assert_eq!(t, parsed);
        }
    }
}
