use inquire::Confirm;
use crate::client::ApiClient;
use crate::config::{PartiriConfig, CONFIG_FILE};
use crate::error::{CliError, Result};
use crate::modules::init::{
prompt_for_pod, prompt_for_project, prompt_for_region, prompt_for_workspace,
};
use crate::output::{ctx, print_success};
pub struct LinkArgs {
pub workspace: Option<String>,
pub project: Option<String>,
pub region: Option<String>,
pub pod: Option<String>,
pub token: Option<String>,
pub clear_token: bool,
}
impl LinkArgs {
fn any_flag(&self) -> bool {
self.workspace.is_some()
|| self.project.is_some()
|| self.region.is_some()
|| self.pod.is_some()
|| self.token.is_some()
|| self.clear_token
}
}
pub fn run(client: &ApiClient, mut config: PartiriConfig, args: LinkArgs) -> Result<()> {
if args.any_flag() {
return run_with_flags(config, args);
}
run_interactive(client, &mut config)
}
fn run_with_flags(mut config: PartiriConfig, args: LinkArgs) -> Result<()> {
if args.workspace.is_some() && args.project.is_none() {
return Err(
"--workspace requires --project (projects don't carry across workspaces).".into(),
);
}
if args.region.is_some() && args.pod.is_none() {
return Err(
"--region requires --pod (pods are scoped to their region's workspace).".into(),
);
}
let mut changed = false;
if let Some(w) = args.workspace {
config.fk_workspace = w;
changed = true;
}
if let Some(p) = args.project {
config.fk_project = p;
changed = true;
}
if let Some(r) = args.region {
config.service.fk_region = r;
changed = true;
}
if let Some(p) = args.pod {
config.service.fk_pod = p;
changed = true;
}
if let Some(t) = args.token {
config.service.fk_service_secret = Some(t);
changed = true;
} else if args.clear_token {
config.service.fk_service_secret = None;
changed = true;
}
if !changed {
println!("No changes.");
return Ok(());
}
config.save()?;
print_success(&format!("{} updated.", CONFIG_FILE));
Ok(())
}
fn run_interactive(client: &ApiClient, config: &mut PartiriConfig) -> Result<()> {
if ctx().no_input {
return Err(Box::new(
CliError::new(
"validation",
"service link in non-interactive mode requires at least one of --workspace, --project, --region, --pod, --token, or --clear-token.",
)
.with_hint(
"Pair --workspace with --project, and --region with --pod. Run 'partiri -j llm context' to find UUIDs.",
)
.enriched(),
));
}
let mut changed = false;
let mut workspace_changed = false;
let mut region_changed = false;
let update_ws = Confirm::new("Update workspace?")
.with_default(false)
.prompt()
.map_err(|_| "Cancelled.")?;
if update_ws {
config.fk_workspace = prompt_for_workspace(Some(client))?;
workspace_changed = true;
changed = true;
}
let update_proj = if workspace_changed {
println!(" Workspace changed — project must be re-selected.");
true
} else {
Confirm::new("Update project?")
.with_default(false)
.prompt()
.map_err(|_| "Cancelled.")?
};
if update_proj {
config.fk_project = prompt_for_project(Some(client), &config.fk_workspace)?;
changed = true;
}
let update_region = Confirm::new("Update region?")
.with_default(false)
.prompt()
.map_err(|_| "Cancelled.")?;
if update_region {
config.service.fk_region = prompt_for_region(Some(client), &config.fk_workspace)?;
region_changed = true;
changed = true;
}
let update_pod = if region_changed {
println!(" Region changed — pod must be re-selected.");
true
} else {
Confirm::new("Update pod?")
.with_default(false)
.prompt()
.map_err(|_| "Cancelled.")?
};
if update_pod {
config.service.fk_pod = prompt_for_pod(Some(client), &config.fk_workspace)?;
changed = true;
}
if !changed {
println!("No changes.");
return Ok(());
}
config.save()?;
print_success(&format!("{} updated.", CONFIG_FILE));
Ok(())
}