//! Rust SCIP indexer install path.
//!
//! Bootstrap of the rust toolchain is delegated to `bootstrap::for_rust()`
//! which uses brew / scoop / winget. After the toolchain is on PATH this
//! module always runs `rustup component add rust-analyzer` — bootstrap
//! returns Ok early when `rustup` already exists, so the component-add
//! step has to live here, not in the bootstrap post-install hook.
//!
//! ## C2: augmented PATH
//!
//! The `rustup` spawn uses `env.augmented_path()` so keg-only brew bin
//! dirs prepended during `RuntimeBootstrap::ensure` are still reachable.

use std::process::Command;

use anyhow::{Context, Result, bail};
use ckg_fs::has_command;

use super::assert_online;
use super::bootstrap::{BootstrapEnv, RuntimeBootstrap};
use super::installer::{InstallCtx, Installer};

pub(super) struct RustInstaller;

impl Installer for RustInstaller {
    fn name(&self) -> &'static str {
        "rust"
    }
    fn install(&self, ctx: &InstallCtx<'_>, env: &dyn BootstrapEnv) -> Result<()> {
        if has_command("rust-analyzer") {
            eprintln!("scip-rust: rust-analyzer already on $PATH — `ckg index` will use it");
            return Ok(());
        }
        RuntimeBootstrap::for_rust().ensure(ctx)?;
        assert_online("install rust-analyzer via rustup")?;
        eprintln!("scip-rust: rustup component add rust-analyzer");
        // C2: inject augmented PATH so the keg-only rustup bin dir found
        // during bootstrap is reachable for this spawn.
        let status = Command::new("rustup")
            .args(["component", "add", "rust-analyzer"])
            .env("PATH", env.augmented_path())
            .status()
            .with_context(|| "spawning rustup")?;
        if !status.success() {
            bail!("rustup component add rust-analyzer exited {status}");
        }
        eprintln!("scip-rust: rust-analyzer installed");
        Ok(())
    }
}
