acton-cli 0.21.0

CLI tool for scaffolding and managing acton-service backend services
use anyhow::Result;
use colored::Colorize;

pub async fn execute(version: String, from: Option<String>, dry_run: bool) -> Result<()> {
    let version_upper = version.to_uppercase();
    let version_lower = version.to_lowercase();

    if dry_run {
        show_dry_run(&version_upper, &from);
        return Ok(());
    }

    println!(
        "{}",
        format!("Adding API version {}...", version_upper).bold()
    );
    println!();

    println!(
        "{}",
        "acton-service uses type-safe API versioning with VersionedApiBuilder.".bold()
    );
    println!();

    if let Some(ref source_version) = from {
        println!(
            "To add {} based on {}:",
            version_upper.cyan(),
            source_version.to_uppercase().cyan()
        );
    } else {
        println!("To add {} to your service:", version_upper.cyan());
    }

    println!();
    println!("{}", "1. Update your main.rs:".green().bold());
    println!();
    println!("   let routes = VersionedApiBuilder::new()");
    println!("       .with_base_path(\"/api\")");

    if let Some(source) = &from {
        let source_upper = source.to_uppercase();
        println!("       // Existing {} routes", source_upper);
        println!(
            "       .add_version(ApiVersion::{}, |routes| {{",
            source_upper
        );
        println!(
            "           routes.route(\"/users\", get(list_users_{}))  // existing",
            source.to_lowercase()
        );
        println!("       }})");
    }

    println!("       // New {} routes", version_upper);
    println!(
        "       .add_version(ApiVersion::{}, |routes| {{",
        version_upper
    );
    println!("           routes");
    println!(
        "               .route(\"/users\", get(list_users_{}))  // your handlers",
        version_lower
    );
    println!(
        "               .route(\"/users/{{id}}\", get(get_user_{}))",
        version_lower
    );
    println!("       }})");
    println!("       .build_routes();");
    println!();

    println!("{}", "2. Create handler functions:".green().bold());
    println!();
    println!(
        "   async fn list_users_{}() -> Json<Vec<User{}>> {{",
        version_lower, version_upper
    );
    println!("       // Implement your logic");
    println!("       Json(vec![])");
    println!("   }}");
    println!();
    println!(
        "   async fn get_user_{}(Path(id): Path<String>) -> Json<User{}> {{",
        version_lower, version_upper
    );
    println!("       // Implement your logic");
    println!("   }}");
    println!();

    if from.is_some() {
        println!(
            "{}",
            "3. Define version-specific types (if schema changed):"
                .green()
                .bold()
        );
        println!();
        println!("   #[derive(Serialize)]");
        println!("   struct User{} {{", version_upper);
        println!("       // Your fields - can differ from other versions");
        println!("   }}");
        println!();
    }

    println!("{}", "4. Optional: Deprecate old versions:".green().bold());
    println!();
    println!("   .add_version_deprecated(");
    println!("       ApiVersion::V1,");
    println!("       |routes| {{ /* routes */ }},");
    println!(
        "       DeprecationInfo::new(ApiVersion::V1, ApiVersion::{})",
        version_upper
    );
    println!("           .with_sunset_date(\"2026-12-31T23:59:59Z\")");
    println!("           .with_message(\"Migrate to {}\")", version_upper);
    println!("   )");
    println!();

    println!("{}", "Example usage:".cyan().bold());
    println!("  GET /api/{}/users", version_lower);
    println!("  GET /api/{}/users/{{id}}", version_lower);
    println!();

    println!("{}", "Learn more:".yellow().bold());
    println!("  See acton-service/examples/users-api.rs for a complete example");

    Ok(())
}

fn show_dry_run(version: &str, from: &Option<String>) {
    println!("\n{}", "Dry run - would show:".bold());
    println!();
    println!("Version: {}", version.cyan());
    if let Some(source) = from {
        println!("Copy from: {}", source.to_uppercase().cyan());
    }
    println!();
    println!(
        "Instructions for adding version {} to your service",
        version
    );
}