use crate::io::{read_composer_json, read_lock};
use crate::utils::{print_info, print_step, print_success};
use anyhow::Result;
use std::path::Path;
pub async fn diagnose(working_dir: &Path) -> Result<()> {
print_step("đ Running diagnostics...");
let mut issues: Vec<String> = Vec::new();
let mut checks_passed = 0;
print_info("Checking composer.json...");
let composer_path = working_dir.join("composer.json");
if !composer_path.exists() {
issues.push("â composer.json not found".to_string());
} else {
match read_composer_json(&composer_path) {
Ok(_) => {
checks_passed += 1;
println!(" â composer.json is valid");
}
Err(e) => {
issues.push(format!("â composer.json is invalid: {e}"));
}
}
}
print_info("Checking composer.lock...");
let lock_path = working_dir.join("composer.lock");
if !lock_path.exists() {
issues.push("â ī¸ composer.lock not found (run 'lectern install')".to_string());
} else {
match read_lock(&lock_path) {
Ok(_) => {
checks_passed += 1;
println!(" â composer.lock is valid");
}
Err(e) => {
issues.push(format!("â composer.lock is invalid: {e}"));
}
}
}
print_info("Checking vendor directory...");
let vendor_path = working_dir.join("vendor");
if !vendor_path.exists() {
issues.push("â ī¸ vendor directory not found (run 'lectern install')".to_string());
} else {
checks_passed += 1;
println!(" â vendor directory exists");
}
print_info("Checking cache directory...");
let cache_dir = crate::core::cache_utils::get_cache_dir();
if cache_dir.exists() {
checks_passed += 1;
println!(" â Cache directory: {}", cache_dir.display());
if let Ok(size) = get_dir_size(&cache_dir) {
println!(
" Cache size: {:.2} MB",
size as f64 / 1024.0 / 1024.0
);
}
} else {
println!(" âšī¸ Cache directory will be created on first use");
}
print_info("Checking PHP availability...");
if let Ok(output) = std::process::Command::new("php")
.arg("--version")
.output()
{
if output.status.success() {
checks_passed += 1;
if let Ok(version) = String::from_utf8(output.stdout) {
let first_line = version.lines().next().unwrap_or("Unknown");
println!(" â {first_line}");
}
}
} else {
issues.push("â ī¸ PHP not found in PATH".to_string());
}
println!("\nđ Diagnostic Summary:");
println!(" Checks passed: {checks_passed}");
println!(" Issues found: {}", issues.len());
if !issues.is_empty() {
println!("\nâ ī¸ Issues:");
for issue in issues {
println!(" {issue}");
}
} else {
print_success("â
No issues detected!");
}
Ok(())
}
fn get_dir_size(path: &Path) -> Result<u64> {
let mut size = 0;
if path.is_dir() {
for entry in std::fs::read_dir(path)? {
let entry = entry?;
let metadata = entry.metadata()?;
if metadata.is_dir() {
size += get_dir_size(&entry.path())?;
} else {
size += metadata.len();
}
}
}
Ok(size)
}