use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AgentMetrics {
    pub queued_records: usize,
    pub retry_count: u64,
    pub heartbeat_sent: u64,
    pub spool_size: u64,
}

impl AgentMetrics {
    pub fn render_prometheus(&self) -> String {
        format!(
            concat!(
                "# HELP awatch_agent_queued_records Local spool records waiting for delivery.\n",
                "# TYPE awatch_agent_queued_records gauge\n",
                "awatch_agent_queued_records {}\n",
                "# HELP awatch_agent_retry_count Total retry attempts performed by the agent.\n",
                "# TYPE awatch_agent_retry_count counter\n",
                "awatch_agent_retry_count {}\n",
                "# HELP awatch_agent_heartbeat_sent Heartbeat envelopes generated by the agent.\n",
                "# TYPE awatch_agent_heartbeat_sent counter\n",
                "awatch_agent_heartbeat_sent {}\n",
                "# HELP awatch_agent_spool_size Local spool size in bytes.\n",
                "# TYPE awatch_agent_spool_size gauge\n",
                "awatch_agent_spool_size {}\n"
            ),
            self.queued_records, self.retry_count, self.heartbeat_sent, self.spool_size
        )
    }
}

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

    #[test]
    fn renders_prometheus_metrics() {
        let metrics = AgentMetrics {
            queued_records: 2,
            retry_count: 3,
            heartbeat_sent: 1,
            spool_size: 512,
        };
        let rendered = metrics.render_prometheus();
        assert!(rendered.contains("awatch_agent_queued_records 2"));
        assert!(rendered.contains("awatch_agent_retry_count 3"));
        assert!(rendered.contains("awatch_agent_heartbeat_sent 1"));
        assert!(rendered.contains("awatch_agent_spool_size 512"));
    }
}
