Skip to content
use crate::version::bump_version;
use std::fs;
use std::path::Path;
use xshell::{Shell, cmd};

pub fn build() -> Result<(), Box<dyn std::error::Error>> {
    let sh = Shell::new()?;

    let cargo_content = fs::read_to_string("Cargo.toml")?;
    let mut cargo_toml: toml::Value = cargo_content.parse()?;

    let (namespace, mode, project_name): (String, String, String) = {
        let spruce = cargo_toml
            .get("spruce")
            .ok_or("No [spruce] section found in Cargo.toml. Please run 'spruce init' first.")?;

        let ns = spruce
            .get("namespace")
            .and_then(|n| n.as_str())
            .ok_or("No namespace found in [spruce] section. Please run 'spruce init' first.")?
            .to_string();

        let md = spruce
            .get("mode")
            .and_then(|m| m.as_str())
            .unwrap_or("alpha")
            .to_string();

        let pn = cargo_toml["package"]["name"]
            .as_str()
            .ok_or("Could not find package name in Cargo.toml")?
            .to_string();

        (ns, md, pn)
    };

    if !Path::new("Dockerfile").exists() {
        eprintln!("Error: Dockerfile not found. Please run 'spruce init' first.");
        std::process::exit(1);
    }

    let current_version = cargo_toml["package"]["version"]
        .as_str()
        .ok_or("Could not find version in Cargo.toml")?
        .to_string();

    let new_version = bump_version(&current_version, &mode)?;

    cargo_toml["package"]["version"] = toml::Value::String(new_version.clone());
    let updated_cargo = toml::to_string_pretty(&cargo_toml)?;
    fs::write("Cargo.toml", updated_cargo)?;
    println!(
        "[OK] Updated Cargo.toml version: {} -> {}",
        current_version, new_version
    );
    println!("  (using '{}' mode)", mode);

    let full_image_name = format!("{}/{}:{}", namespace, project_name, new_version);
    let latest_image_name = format!("{}/{}:latest", namespace, project_name);

    println!("\nBuilding Docker image: {}", full_image_name);

    cmd!(
        sh,
        "docker build -t {full_image_name} -t {latest_image_name} ."
    )
    .run()?;

    println!("[OK] Successfully built image: {}", full_image_name);
    println!("[OK] Tagged as: {}", latest_image_name);

    Ok(())
}