use anyhow::Result;
use aws_sdk_ssm::Client;
use aws_sdk_ssm::types::{Parameter, ParameterType};
use colored::Colorize;
use std::collections::BTreeMap;
use crate::app::{app_prefix, resolve_app};
use crate::config::prefix_root;
use crate::env_map::parse_tags;
use crate::ssm::{
get_parameters_by_names, get_parameters_by_path, names_filtered_by_tags, ssm_name_to_env_key,
ssm_name_to_env_key_from_root,
};
use crate::util::print_entry;
pub async fn cmd_list(
client: &Client,
app: Option<String>,
all: bool,
keys_only: bool,
raw_tags: Vec<String>,
) -> Result<()> {
let prefix = if all {
prefix_root().to_string()
} else {
app_prefix(&resolve_app(app)?)
};
let tag_filters = parse_tags(&raw_tags)?;
let params: Vec<Parameter> = if tag_filters.is_empty() {
get_parameters_by_path(client, &prefix).await?
} else {
let names = names_filtered_by_tags(client, &tag_filters, Some(&prefix)).await?;
if names.is_empty() {
println!("(no parameters match tag filter under {})", prefix.dimmed());
return Ok(());
}
get_parameters_by_names(client, &names).await?
};
if params.is_empty() {
println!("(no parameters under {})", prefix.dimmed());
return Ok(());
}
if all {
let prefix_slash = format!("{}/", prefix_root());
let mut by_app: BTreeMap<String, Vec<(String, String, bool)>> = BTreeMap::new();
for p in ¶ms {
let name = p.name().unwrap_or_default();
let rest = name.strip_prefix(&prefix_slash).unwrap_or(name);
let (app_name, _) = rest.split_once('/').unwrap_or((rest, ""));
let key = ssm_name_to_env_key_from_root(name, prefix_root());
let value = p.value().unwrap_or_default().to_string();
let secure = matches!(p.r#type(), Some(&ParameterType::SecureString));
by_app
.entry(app_name.to_string())
.or_default()
.push((key, value, secure));
}
for (app_name, mut entries) in by_app {
entries.sort_by(|a, b| a.0.cmp(&b.0));
println!("{}", format!("[{}]", app_name).bold().cyan());
for (k, v, secure) in entries {
print_entry(&k, Some(&v), secure, keys_only, " ");
}
}
} else {
let mut entries: Vec<(String, String, bool)> = params
.iter()
.map(|p| {
let key = ssm_name_to_env_key(p.name().unwrap_or_default(), &prefix);
let value = p.value().unwrap_or_default().to_string();
let secure = matches!(p.r#type(), Some(&ParameterType::SecureString));
(key, value, secure)
})
.collect();
entries.sort_by(|a, b| a.0.cmp(&b.0));
println!(
"{}",
format!("# {} ({} variables)", prefix, entries.len()).dimmed()
);
for (k, v, secure) in entries {
print_entry(&k, Some(&v), secure, keys_only, "");
}
}
Ok(())
}