use std::collections::HashMap;
use anyhow::Result;
use clap::Parser;
use crate::cli::{input_vec_to_hashmap, CliConnectionOpts, CommandOutput};
use crate::common::find_host_id;
use crate::component::{scale_component, ScaleComponentArgs};
use crate::config::WashConnectionOptions;
use crate::context::default_component_operation_timeout_ms;
use super::start::resolve_ref;
use super::validate_component_id;
#[derive(Debug, Clone, Parser)]
pub enum ScaleCommand {
#[clap(name = "component")]
Component(ScaleComponentCommand),
}
#[derive(Debug, Clone, Parser)]
pub struct ScaleComponentCommand {
#[clap(flatten)]
pub opts: CliConnectionOpts,
#[clap(name = "host-id")]
pub host_id: String,
#[clap(name = "component-ref")]
pub component_ref: String,
#[clap(name = "component-id", value_parser = validate_component_id)]
pub component_id: String,
#[clap(short = 'c', long = "max-instances", alias = "max-concurrent", alias = "max", alias = "count", default_value_t = u32::MAX)]
pub max_instances: u32,
#[clap(short = 'a', long = "annotations")]
pub annotations: Vec<String>,
#[clap(long = "config")]
pub config: Vec<String>,
#[clap(long = "skip-wait")]
pub skip_wait: bool,
#[clap(long = "wait-timeout-ms", default_value_t = default_component_operation_timeout_ms())]
pub wait_timeout_ms: u64,
}
pub async fn handle_scale_component(cmd: ScaleComponentCommand) -> Result<CommandOutput> {
let wco: WashConnectionOptions = cmd.opts.try_into()?;
let client = wco.into_ctl_client(None).await?;
let annotations = input_vec_to_hashmap(cmd.annotations)?;
let component_ref = resolve_ref(&cmd.component_ref).await?;
let info = scale_component(ScaleComponentArgs {
client: &client,
host_id: &find_host_id(&cmd.host_id, &client).await?.0,
component_id: &cmd.component_id,
component_ref: &component_ref,
max_instances: cmd.max_instances,
annotations: Some(annotations),
config: cmd.config,
skip_wait: cmd.skip_wait,
timeout_ms: None,
})
.await?;
let scale_msg = if cmd.max_instances == u32::MAX {
"unbounded concurrency".to_string()
} else {
format!("{} max concurrent instances", cmd.max_instances)
};
let text = format!(
"Component [{}] (ref: [{}]) scaled on host [{}] to {scale_msg}",
info.component_id, info.component_ref, info.host_id,
);
Ok(CommandOutput::new(
text.clone(),
HashMap::from([
("host_id".into(), info.host_id.into()),
("component_id".into(), info.component_id.into()),
("component_ref".into(), info.component_ref.into()),
("result".into(), text.into()),
]),
))
}