use std::time::Instant;
use rmcp::ErrorData as McpError;
use rmcp::model::{CallToolResult, RawContent};
use serde_json::Value;
use super::ServerState;
fn result_text(result: &CallToolResult) -> std::borrow::Cow<'_, str> {
let mut texts = result.content.iter().filter_map(|c| match &c.raw {
RawContent::Text(t) => Some(t.text.as_str()),
_ => None,
});
let Some(first) = texts.next() else {
return std::borrow::Cow::Borrowed("");
};
match texts.next() {
None => std::borrow::Cow::Borrowed(first),
Some(second) => {
let mut text = String::with_capacity(first.len() + second.len());
text.push_str(first);
text.push_str(second);
for rest in texts {
text.push_str(rest);
}
std::borrow::Cow::Owned(text)
}
}
}
pub(super) fn record_call(
state: &ServerState,
tool: &'static str,
params: &Value,
started: Instant,
result: &Result<CallToolResult, McpError>,
) {
let Ok(r) = result else { return };
let elapsed_ms: u64 = started.elapsed().as_millis().try_into().unwrap_or(u64::MAX);
let resp_text = result_text(r);
let resp_bytes = resp_text.len() as u64;
let corpus = state
.corpus_bytes
.load(std::sync::atomic::Ordering::Relaxed);
let savings = super::savings::estimate_from_text(tool, corpus, resp_text.as_ref());
state
.telemetry
.record(tool, params, resp_bytes, elapsed_ms, &savings);
}