1use anyhow::{Context, Result};
7
8use raps_kernel::http;
9
10use crate::DesignAutomationClient;
11use crate::types::*;
12
13impl DesignAutomationClient {
14 pub fn nickname(&self) -> &str {
16 self.config.da_nickname.as_deref().unwrap_or("default")
17 }
18
19 pub async fn effective_nickname(&self) -> Result<String> {
24 if let Some(ref nick) = self.config.da_nickname {
25 return Ok(nick.clone());
26 }
27 let token = self.auth.get_token().await?;
28 let url = format!("{}/forgeapps/me", self.config.da_url());
29 let response = http::send_with_retry(&self.config.http_config, || {
30 self.http_client.get(&url).bearer_auth(&token)
31 })
32 .await?;
33 if response.status().is_success() {
34 let text = response.text().await.unwrap_or_default();
35 let trimmed = text.trim().trim_matches('"');
37 if !trimmed.is_empty() {
38 return Ok(trimmed.to_string());
39 }
40 }
41 Ok("default".to_string())
42 }
43
44 pub async fn list_engines(&self) -> Result<Vec<String>> {
49 let token = self.auth.get_token().await?;
50 let url = format!("{}/engines", self.config.da_url());
51
52 let response = http::send_with_retry(&self.config.http_config, || {
53 self.http_client.get(&url).bearer_auth(&token)
54 })
55 .await?;
56
57 if !response.status().is_success() {
58 let status = response.status();
59 let error_text = response.text().await.unwrap_or_default();
60 anyhow::bail!("Failed to list engines ({status}): {error_text}");
61 }
62
63 let paginated: PaginatedResponse<String> = response
64 .json()
65 .await
66 .context("Failed to parse engines response")?;
67
68 Ok(paginated.data)
69 }
70
71 pub async fn list_engines_detailed(&self) -> Result<Vec<Engine>> {
76 let token = self.auth.get_token().await?;
77 let base_url = format!("{}/engines", self.config.da_url());
78 let mut all_engines = Vec::new();
79 let mut page_token: Option<String> = None;
80
81 loop {
82 let url = match &page_token {
83 Some(tok) => format!("{base_url}?page={tok}"),
84 None => base_url.clone(),
85 };
86
87 let token_clone = token.clone();
88 let response = http::send_with_retry(&self.config.http_config, || {
89 self.http_client.get(&url).bearer_auth(&token_clone)
90 })
91 .await?;
92
93 if !response.status().is_success() {
94 let status = response.status();
95 let error_text = response.text().await.unwrap_or_default();
96 anyhow::bail!("Failed to list engines ({status}): {error_text}");
97 }
98
99 let paginated: PaginatedResponse<String> = response
100 .json()
101 .await
102 .context("Failed to parse engines response")?;
103
104 for id in paginated.data {
107 let description = id
108 .split('.')
109 .next_back()
110 .map(|s| s.replace('+', " "))
111 .unwrap_or_default();
112 all_engines.push(Engine {
113 id,
114 description: Some(description),
115 product_version: None,
116 });
117 }
118
119 match paginated.pagination_token {
120 Some(tok) if !tok.is_empty() => page_token = Some(tok),
121 _ => break,
122 }
123 }
124
125 Ok(all_engines)
126 }
127}