use std::slice;
use anyhow::{Context, Result};
use clap::{ArgGroup, Args, Subcommand};
use ironflow_sdk::IronflowClient;
use ironflow_sdk::types::{CreateUserRequest, UpdateRoleRequest};
use uuid::Uuid;
use crate::confirm::{confirm, resolve_secret_value};
use crate::output;
#[derive(Debug, Args)]
pub struct UserArgs {
#[command(subcommand)]
pub command: UserCommands,
}
#[derive(Debug, Subcommand)]
pub enum UserCommands {
List,
Create {
username: String,
#[arg(long)]
email: String,
#[arg(long)]
password: Option<String>,
#[arg(long)]
admin: bool,
},
Delete {
id: Uuid,
#[arg(long)]
yes: bool,
},
#[command(group(ArgGroup::new("role").required(true).args(["admin", "member"])))]
SetRole {
id: Uuid,
#[arg(long)]
admin: bool,
#[arg(long)]
member: bool,
},
}
pub async fn execute(client: &IronflowClient, args: &UserArgs, json_mode: bool) -> Result<()> {
match &args.command {
UserCommands::List => {
let response = client.list_users().await?;
output::print_output(json_mode, &response, || output::users_table(&response.data))?;
}
UserCommands::Create {
username,
email,
password,
admin,
} => {
let password = resolve_secret_value(password.as_deref(), "password")?;
let request: CreateUserRequest = CreateUserRequest::builder()
.username(username.clone())
.email(email.clone())
.password(password)
.is_admin(*admin)
.try_into()
.context("failed to build CreateUserRequest")?;
let response = client.create_user(&request).await?;
output::print_output(json_mode, &response, || {
output::users_table(slice::from_ref(&response.data))
})?;
}
UserCommands::Delete { id, yes } => {
confirm(&format!("Delete user '{id}'?"), *yes)?;
client.delete_user(*id).await?;
output::report_deletion(json_mode, "user", id.to_string())?;
}
UserCommands::SetRole { id, admin, .. } => {
let request: UpdateRoleRequest = UpdateRoleRequest::builder()
.is_admin(*admin)
.try_into()
.context("failed to build UpdateRoleRequest")?;
let response = client.update_role(*id, &request).await?;
output::print_output(json_mode, &response, || {
output::users_table(slice::from_ref(&response.data))
})?;
}
}
Ok(())
}