use anyhow::Result;
use colored::Colorize;
use std::collections::HashMap;
use std::path::PathBuf;
use crate::error::CliError;
use super::templates;
pub async fn init_c_project(
project_name: &str,
custom_path: Option<&str>,
json_format: bool,
) -> Result<(), CliError> {
if !json_format {
println!(
"{}",
format!("Initializing C project: {}", project_name).cyan()
);
}
let project_dir = if let Some(path) = custom_path {
PathBuf::from(path).join(project_name)
} else {
PathBuf::from(project_name)
};
if project_dir.exists() {
return Err(CliError::Generic {
message: format!(
"Directory '{}' already exists. Please choose a different name or location.",
project_dir.display()
),
});
}
tokio::fs::create_dir_all(&project_dir)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create project directory: {}", e),
})?;
let examples_dir = project_dir.join("examples");
tokio::fs::create_dir_all(&examples_dir)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create examples directory: {}", e),
})?;
let program_name = templates::sanitize_program_name(project_name);
let mut vars = HashMap::new();
vars.insert("PROJECT_NAME".to_string(), project_name.to_string());
vars.insert("PROGRAM_NAME".to_string(), program_name.clone());
let gnumakefile_path = project_dir.join("GNUmakefile");
let gnumakefile_content = templates::replace_template_vars(templates::GNUMAKEFILE_TEMPLATE, &vars);
tokio::fs::write(&gnumakefile_path, gnumakefile_content)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create GNUmakefile: {}", e),
})?;
let local_mk_path = examples_dir.join("Local.mk");
let local_mk_content = templates::replace_template_vars(templates::LOCAL_MK_TEMPLATE, &vars);
tokio::fs::write(&local_mk_path, local_mk_content)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create Local.mk: {}", e),
})?;
let program_c_path = examples_dir.join(format!("{}.c", program_name));
let program_c_content =
templates::replace_template_vars(templates::PROGRAM_C_TEMPLATE, &vars);
tokio::fs::write(&program_c_path, program_c_content)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create program source file: {}", e),
})?;
let readme_path = project_dir.join("README.md");
let readme_content = templates::replace_template_vars(templates::README_TEMPLATE, &vars);
tokio::fs::write(&readme_path, readme_content)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create README.md: {}", e),
})?;
let gitignore_path = project_dir.join(".gitignore");
tokio::fs::write(&gitignore_path, templates::GITIGNORE_TEMPLATE)
.await
.map_err(|e| CliError::Generic {
message: format!("Failed to create .gitignore: {}", e),
})?;
if json_format {
println!(
"{{\"status\":\"success\",\"project\":\"{}\",\"path\":\"{}\"}}",
project_name,
project_dir.display()
);
} else {
println!(
"\n{}",
"✓ Project initialized successfully".green().bold()
);
println!("\nCreated files:");
println!(" {}", gnumakefile_path.display());
println!(" {}", readme_path.display());
println!(" {}", gitignore_path.display());
println!(" {}", local_mk_path.display());
println!(" {}", program_c_path.display());
println!("\n{}", "Next steps:".cyan().bold());
println!(" 1. cd {}", project_name);
println!(" 2. make -j");
println!(
" 3. Deploy with: thru uploader upload <seed> build/thruvm/bin/{}_c.bin",
program_name
);
}
Ok(())
}
pub async fn init_cpp_project(
_project_name: &str,
_custom_path: Option<&str>,
json_format: bool,
) -> Result<(), CliError> {
if json_format {
println!("{{\"status\":\"error\",\"message\":\"C++ projects not yet implemented\"}}");
} else {
println!("{}", "C++ project initialization is not yet implemented.".yellow());
println!("This feature will be available in a future release.");
}
Ok(())
}
pub async fn init_rust_project(
_project_name: &str,
_custom_path: Option<&str>,
json_format: bool,
) -> Result<(), CliError> {
if json_format {
println!("{{\"status\":\"error\",\"message\":\"Rust projects not yet implemented\"}}");
} else {
println!("{}", "Rust project initialization is not yet implemented.".yellow());
println!("This feature will be available in a future release.");
}
Ok(())
}