//! Message types for LLM communication

use serde::{Deserialize, Serialize};

/// Message role in conversation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Role {
    /// System prompt (instructions, context)
    #[serde(rename = "system")]
    System,

    /// User message
    #[serde(rename = "user")]
    User,

    /// Assistant response
    #[serde(rename = "assistant")]
    Assistant,
}

/// A message in the conversation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
    /// Role of message sender
    pub role: Role,

    /// Message content
    pub content: String,
}

impl Message {
    /// Create a system message
    pub fn system(content: impl Into<String>) -> Self {
        Message {
            role: Role::System,
            content: content.into(),
        }
    }

    /// Create a user message
    pub fn user(content: impl Into<String>) -> Self {
        Message {
            role: Role::User,
            content: content.into(),
        }
    }

    /// Create an assistant message
    pub fn assistant(content: impl Into<String>) -> Self {
        Message {
            role: Role::Assistant,
            content: content.into(),
        }
    }

    /// Get approximate token count (rough estimate: 1 token ≈ 4 chars)
    pub fn estimate_tokens(&self) -> usize {
        (self.content.len() / 4) + 10 // Buffer for metadata
    }
}

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

    #[test]
    fn test_message_creation() {
        let msg = Message::user("Hello");
        assert_eq!(msg.role, Role::User);
        assert_eq!(msg.content, "Hello");
    }

    #[test]
    fn test_message_system() {
        let msg = Message::system("You are helpful");
        assert_eq!(msg.role, Role::System);
    }

    #[test]
    fn test_message_assistant() {
        let msg = Message::assistant("Response");
        assert_eq!(msg.role, Role::Assistant);
    }

    #[test]
    fn test_token_estimation() {
        let msg = Message::user("Hello world");
        let tokens = msg.estimate_tokens();
        assert!(tokens > 0);
    }
}
