1use chrono::{TimeZone, Utc};
2use url::Url;
3
4use crate::logs::LogsQuery;
5
6pub enum DatadogResource {
7 Logs(LogsQuery),
8}
9
10pub fn parse_datadog_url(url_str: &str) -> Result<DatadogResource, String> {
11 let parsed = Url::parse(url_str).map_err(|e| format!("Invalid URL: {}", e))?;
12
13 let host = parsed.host_str().unwrap_or("");
15 if !host.contains("datadoghq.com") {
16 return Err("URL must be a Datadog URL (*.datadoghq.com)".to_string());
17 }
18
19 let path = parsed.path();
20
21 let params: std::collections::HashMap<_, _> = parsed.query_pairs().collect();
23
24 match path {
25 "/logs" => {
26 let query = params
27 .get("query")
28 .map(|s| s.to_string())
29 .unwrap_or_else(|| "*".to_string());
30
31 let from = params
33 .get("from_ts")
34 .and_then(|ts| ts.parse::<i64>().ok())
35 .map(|ms| {
36 Utc.timestamp_millis_opt(ms)
37 .single()
38 .map(|dt| dt.to_rfc3339())
39 .unwrap_or_else(|| "now-15m".to_string())
40 })
41 .unwrap_or_else(|| "now-15m".to_string());
42
43 let to = params
44 .get("to_ts")
45 .and_then(|ts| ts.parse::<i64>().ok())
46 .map(|ms| {
47 Utc.timestamp_millis_opt(ms)
48 .single()
49 .map(|dt| dt.to_rfc3339())
50 .unwrap_or_else(|| "now".to_string())
51 })
52 .unwrap_or_else(|| "now".to_string());
53
54 Ok(DatadogResource::Logs(LogsQuery::new(query, from, to, 100)))
55 }
56 _ => Err(format!(
57 "Unsupported Datadog resource: {}. Currently only /logs is supported.",
58 path
59 )),
60 }
61}